R语言实现:同ID受试者疾病状态变化时的密度差值计算
R代码实现随访数据疾病状态变化下的密度差计算
实现逻辑说明
处理流程完全匹配需求规则:
- 按受试者ID分组,对随访记录按检测日期升序排列
- 仅识别同一受试者相邻随访节点的疾病状态变化,跳过连续相同疾病状态的非变化节点
- 仅对状态发生跳转的相邻两条记录计算密度差值,自动排除全程无状态变化的受试者
- 最终输出字段包含受试者ID、跳转前疾病状态、跳转后疾病状态、密度变化值
依赖包
使用dplyr处理分组数据,lubridate做标准日期格式转换,未安装可先运行安装命令:
install.packages(c("dplyr", "lubridate")) library(dplyr) library(lubridate)
示例数据构造
先构造和需求描述一致的3位受试者测试数据,方便验证效果:
# 构造示例随访数据集 follow_up_data <- data.frame( `Subject ID` = c(1,1,1, 2,2, 3,3,3), Density = c(32,35,37, 28,41, 22,25,39), Disease = c("Healthy","Healthy","Healthy", "Healthy","Mild", "Mild","Mild","Severe"), Date = c("2021/1/5","2021/6/10","2021/12/3", "2021/2/2","2021/8/15", "2020/9/12","2021/3/8","2021/9/21"), check.names = FALSE )
测试集对应规则验证点:
- Subject 1全程为Healthy状态,无变化,最终会被自动排除
- Subject 2从Healthy转为Mild,计算对应两次记录的密度差
- Subject 3前两次随访都是Mild状态,仅在2021/9/21转为Severe,仅计算2021/3/8和2021/9/21的密度差
核心处理代码
result <- follow_up_data %>% # 把字符串格式日期转为标准日期格式,避免字符排序错误 mutate(Date = ymd(Date)) %>% # 按受试者ID分组 group_by(`Subject ID`) %>% # 组内按检测日期从早到晚排序 arrange(Date, .by_group = TRUE) %>% # 提前每条记录相邻下一条随访的疾病状态、密度值 mutate( next_disease = lead(Disease, n = 1), next_density = lead(Density, n = 1) ) %>% # 仅保留相邻节点疾病状态发生变化的记录,过滤无变化、最后一条无后续随访的记录 filter(!is.na(next_disease), Disease != next_disease) %>% # 计算密度差,整理为要求的输出字段 transmute( `Subject ID` = `Subject ID`, `Original Disease` = Disease, `New Disease` = next_disease, `Change in density` = next_density - Density ) %>% # 解除分组返回普通数据框 ungroup()
结果验证
运行代码后输出的result内容如下,完全符合需求规则:
| Subject ID | Original Disease | New Disease | Change in density |
|---|---|---|---|
| 2 | Healthy | Mild | 13 |
| 3 | Mild | Severe | 14 |
注:如果需要调整密度差计算方向(如下降为负、上升为正的反向逻辑),把密度差计算语句改为
Density - next_density即可;如果存在同一天多次检测的场景,可在arrange步骤增加排序维度调整记录优先级。
内容的提问来源于stack exchange,提问作者corey
相关产品推荐
相关产品推荐

