PSM倾向得分匹配
<h1>背景</h1><p>目的是在病例组数据集和对照组数据集里面进行快速的1:1匹配。要求性别相同,年龄不超过两岁。。虽然不是作图的。但估计群里好多临床的人肯定也特别想用的。如果CASE1和CONTROL1匹配后,那么尽管CASE3和CONTROL1原来可以匹配,此时就不能再匹配了。</p>
<p>以上就是倾向得分匹配(PSM)。PSM是一种用来评估处置效应的统计方法。广义说来,它将样本根据其特性分类,而不同类样本间的差异就可以看作处置效应的无偏估计。因此,PSM不仅仅是随机试验的一种替代方法,它也是流行病研究中进行样本比较的重要方法之一。</p>
<p>有R包已经把各种情况考虑进去,帮助我们轻松的完成倾向得分匹配。</p>
<h1>使用场景</h1>
<p>与健康相关的生活质量(HRQOL)被认为是癌症治疗的重要结果之一。对癌症患者而言,最常用的HRQOL测度是通过欧洲癌症研究与治疗中心的调查问卷计算得出的。EORTC QLD-C30是一个由30个项目组成,包括5个功能量表,9个症状量表和一个全球生活质量量表的的问卷。所有量表都会给出一个0-100之间的得分。症状量表得分越高代表被调查人生活压力越大,其余两个量表得分越高代表生活质量越高。</p>
<p>然而,如果没有任何参照,直接对数据进行解释是很困难的。幸运的是,EORTC QLQ-C30问卷也在一些一般人群调查中使用,我们可以对比患者的得分和一般人群的得分差异,从而判断患者的负担症状和一些功能障碍是否能归因于癌症治疗。PSM在这里可以以年龄和性别等特征,将相似的患者和一般人群进行匹配。</p>
<p>代码和说明信息来源于以下资料:</p>
<p>原文:https://datascienceplus.com/how-to-use-r-for-matching-samples-propensity-score/</p>
<p>译文:http://www.ituring.com.cn/article/260460</p>
<h1>生成输入数据</h1>
<p>如果你自己有数据,保存成easy_input.txt那样的格式,就可以跳过“生成输入数据”这步,直接进入“倾向得分匹配”;</p>
<h1>生成患者人群</h1>
<p>创建一个名为df.patients的数据框,我希望它包含250个病人的年龄和性别数据,所有病人的年龄都要在30-78岁之间,并且70%的病人被设定为男性。</p>
<pre><code class="language-{r}">#install.packages("wakefield")
rm(list = ls())####魔幻操作,一键清空~
getwd()
library(wakefield)
set.seed(1234)
df.patients <- r_data_frame(n = 250,
age(x = 30:78,
name = 'Age'),
sex(x = c("Male", "Female"),
prob = c(0.70, 0.30),
name = "Sex"))
df.patients$Sample <- as.factor('CASE')
df.patients$ID<-paste("CASE",rownames(df.patients),sep = "")
summary(df.patients)
</code></pre>
<h1>生成正常对照人群</h1>
<p>创建一个名为df.population的数据框。我希望这个数据集的数据和患者的有些不同,因此正常人群的年龄区间被设定为18-80岁,并且男女各占一半。</p>
<pre><code class="language-{r}">set.seed(1234)
df.population <- r_data_frame(n = 1000,
age(x = 18:80,
name = 'Age'),
sex(x = c("Male", "Female"),
prob = c(0.50, 0.50),
name = "Sex"))
df.population$Sample <- as.factor('CONTROL')
df.population$ID<-paste("CONTROL",rownames(df.population),sep = "")
summary(df.population)
</code></pre>
<h1>合并人群</h1>
<p>把上面这两个数据框合并,也就是把患者混进正常人群,这样就模拟出一个自然人群,完成了全部的准备工作。</p>
<pre><code class="language-{r}">mydata <- rbind(df.patients, df.population)
mydata$Group <- as.logical(mydata$Sample == 'CASE')
head(mydata)
tail(mydata)
write.table(mydata,"easy_input.txt",row.names = F,quote = F,sep = "\t")
</code></pre>
<p>mydata前几行如下:<br />
<img src="https://ipfs.io/ipfs/QmNMuFrxF1xHw5198oGZ7gDFBQL9JwuXSW4Hj7wepey9Lv" alt="" /></p>
<h1>倾向得分匹配</h1>
<p>生成匹配的病例组数据集和对照组数据集</p>
<p>用MatchIT包中的matchit函数来匹配两类样本</p>
<pre><code class="language-{r}">#install.packages("MatchIt")
library(MatchIt)
#要找年龄最接近的,因此选用method=‘nearest’。
#ratio=1意味着这是一一配对
#同时也请注意Group变量需要是逻辑型变量
set.seed(1234)
match.it <- matchit(Group ~ Age + Sex, data = mydata, method="nearest", ratio=1)
plot(match.it, type = 'jitter', interactive = FALSE)
</code></pre>
<p><img src="https://ipfs.io/ipfs/QmUCHuTwa4o8w6Cbv949dBMUEfhXoX2kuy5udewcLvTMoE" alt="" /></p>
<h1>生成CASE-CONTROL一一配对的格式</h1>
<pre><code class="language-{r}">df.match <- match.data(match.it)
df<-df.match#按年龄排序
df<-df#按性别排序
df<-df#按组排序
#配对
dfpairinfo<-data.frame(df$ID,df$Age,df$Sex,df$ID,df$Age,df$Sex)
colnames(dfpairinfo)<-c("CASEID","CASEage","CASEgender","CONTROLID","CONTROLage","CONTROLgender")
head(dfpairinfo)
write.table(dfpairinfo,"pair_info.txt",quote = F,sep = "\t",row.names = F )
dfpair<-data.frame(df$ID,df$ID)
colnames(dfpair)<-c("CASEID","CONTROLID")
head(dfpair)
write.table(dfpair,"pair_ID.txt",quote = F,sep = "\t",row.names = F )
</code></pre>
<p>dfpair前几行如下:<br />
<img src="https://ipfs.io/ipfs/QmRGKgG7gE6HcPLj8Yqyvn9YP8VB7ZvHWgZHuoMfCuw9CZ" alt="" /></p>
<h1>后记</h1>
<p>这样的随机匹配,用于临床队列研究,大致是合理的,排除了混杂因素(年龄、性别)。</p>
页:
[1]