使用R tidyverse筛选首测Test B一年内的Test A数据
使用tidyverse处理临床随访数据:匹配首次Test B±1年内最近的Score_A值
需求说明
现有数据集包含受试者Id、访视编码VISIT、访视时间Time、Score_A、Score_B字段:
- Test A从研究启动即开展,但并非每次访视都进行;
- Test B开展时间较晚(通常在第5次访视,部分受试者为其他访视)。
需要构建一个截面数据集:
- 提取每位受试者首次完成Test B的记录(即首次非缺失
Score_B的行); - 为该记录匹配对应的
Score_A:取该Test B时间点±1年范围内,最近的非缺失Score_A值。
现有尝试代码未考虑±1年的时间范围限制,导致受试者2的Score_A为缺失值,需完善代码。
示例数据
mydata <- data.frame(Id=c(1,1,1,1,1,1,1,1, 2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3), VISIT=c(1,2,3,4,5,6,7,8, 1,2,3,4,5,6,7,8, 1,2,3,4,5,6,7,8), Time=c(0,1.1,1.9,3,4,5.1,6.1,6.9, 0,.9,2.1,3.1,4.1,5,6.1,7.2, 0,1,2.1,3.2,3.9,5.1,6,7.1), Score_A=c(10,9,9,8,7,10,10,8, 5,9,4,3,NA,13,14,18, 9,9,10,11,NA,14,12,13), Score_B=c(NA,NA,NA,NA,100,NA,90,NA, NA,NA,NA,NA,80,NA,99,NA, NA,NA,NA,NA,75,NA,97,NA) )
期望输出
desired_output <- data.frame(Id=c(1,2,3), Score_A=c(7,13,11), Score_B=c(100,80,75))
尝试的代码(未考虑±1年范围)
Q <- mydata %>% group_by(Id) %>% arrange(Time, .by_group = T) %>% filter(!is.na(Score_B)) %>% slice(1)
完善后的代码
library(tidyverse) result <- mydata %>% # 按受试者分组,提取首次Test B的记录,保留关键信息 group_by(Id) %>% filter(!is.na(Score_B)) %>% arrange(Time, .by_group = TRUE) %>% slice(1) %>% select(Id, Time_B = Time, Score_B) %>% ungroup() %>% # 关联原数据集,筛选同一受试者下Time在Test B时间±1年内的记录 inner_join(mydata %>% select(Id, Time, Score_A), by = "Id") %>% filter(Time >= Time_B - 1, Time <= Time_B + 1) %>% filter(!is.na(Score_A)) %>% # 计算时间差,取最近的非缺失Score_A group_by(Id) %>% mutate(time_diff = abs(Time - Time_B)) %>% arrange(time_diff, .by_group = TRUE) %>% slice(1) %>% # 保留目标字段 select(Id, Score_A, Score_B) %>% ungroup()
验证结果
运行上述代码后,result与desired_output完全一致:
> result # A tibble: 3 × 3 Id Score_A Score_B <dbl> <dbl> <dbl> 1 1 7 100 2 2 13 80 3 3 11 75
内容的提问来源于stack exchange,提问作者inprogress123
相关产品推荐
相关产品推荐

