vlambda博客
学习文章列表

基于R语言实现病例与对照的匹配

病例对照研究(case control study)是以确诊的患有某特定疾病的一组病人作为病例组(case),以不患有该病但具有可比性的一组个体作为对照组(control),通过比较两组中我们关心的暴露因素的比例,从而推断暴露因素和疾病之间的关联。那么该如何确保病例组和对照组有可比性呢,这就不得不提到匹配。
匹配一般包括频数匹配和个体匹配。频数匹配只需要确保匹配的因素在两组数据中比例相同,比如说病例组中男女比例为1:1,那么在对照组中也应该同样是1:1。个体匹配则要求对于病例组中的每一个研究对象,对照组中必须有一个匹配因素一致或相近的研究对象与之匹配。例如病例组中有一位35岁的男性,那么对照组中也应该有一个35岁左右的男性与之匹配。
本文将基于R语言实现病例与对照的1:1匹配,而1对多只要在此基础上进行稍微的修改即可完成。
本文使用xlsx包对数据进行读取和保存,如若你在之前没有安装过xlsx,那么你需要在RStudio的console下运行install.packages("xlsx")进行安装。利用R语言完成病例与对照的1:1匹配可以分为以下6步:
第1步,我们需要利用xlsx包从excel文件中读取我们需要的数据。

library(xlsx)
#加载excel数据
data_case = read.xlsx("data.xlsx", sheetIndex = 1)

数据在读取之后将以dataframe的格式存在,数据读取的结果如下图所示:

在匹配过程中,本文将会使agelevel与sex保持一致,实现extant的1:1对应。
第2步,我们需要对读取的数据进行一些操作。一是在数据中添加group列代表研究对象的分组(此时的分组只是初始化分组,没有实现1:1匹配);二是根据匹配因素(sex和agelevel)将数据进行划分为一个个子dataframe。在这些子dataframe中,所有研究对象的sex和agelevel都是一致的。

data_case$group <- c(1:length(data_case$sex))
data_case <- split(data_case, list(data_case$sex, data_case$agelevel))

第3步,我们需要初始化一个保存结果的列表和记录分组的变量。

data_result <- list()
group_index = 0

第4步,我们就到达了本文实现研究对象匹配的重点,遍历每一个子dataframe,并按照extent一一对应的方式对研究对象进行分组。

for(i in data_case){
# 按照extent划分
data_split <- split(i, i$extant)
if(length(data_split) > 1){
a = data_split$`0`
b = data_split$`1`
# 确保a中研究对象数量少于b
if(length(a$extant) > length(b$extant)){
tmp = b
b = a
a = tmp
}
group_number = length(a$extant)
# 对a中的研究对象分配组
for(i in c(0:(group_number-1))){
a[i+1,]$group <- group_index + i
}
# 对b中的研究对象分配组
for(i in c(0:(length(b$extant)-1))){
if (i < group_number){
b[i+1,]$group <- group_index + i%%group_number
}
else{
# -1表示数据没有被使用到
b[i+1,]$group <- -1
}
}
# 保存到data_result中
data_result <- c(data_result, list(a))
data_result <- c(data_result, list(b))
group_index <- group_index + group_number
}
}

第5步,我们需要融合data_result中的子dataframe。

data_split <- data_result
data_result = data_split[1][[1]]
for(i in c(2:length(data_split))){
data_result <- rbind(data_result, data_split[i][[1]])
}

第6步,按照组对数据进行排序。

data_result <- data_result[order(data_result$group),]

匹配之后的数据如下图所示:

利用以上代码即可实现病例与对照的1:1匹配,如果你想实现病例与对照的一对多匹配,只需要在第4步中增添一些判断语句并对研究对象的分组过程进行稍微的修改即可完成。