如何筛选先患疾病1后患疾病2(可间隔其他疾病)的个体?
筛选满足疾病先后顺序的患者
给定包含患者多次就诊记录的DataFrame,我们需要筛选出先出现疾病1、之后出现疾病2的患者(疾病1与疾病2之间可存在疾病3),最终目标是得到ID为2、4、6的个体。
原始数据
ID <- c(1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 6) Visit <- c(1, 2, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 1, 2, 3) Disease <- c(2, 2, 1, 2, 1, 1, 1, 1, 2, 1, 2, 2, 1, 1, 3, 2) df <- data.frame(ID, Visit, Disease)
解决方案1:用dplyr分组处理
这是日常数据处理中常用的tidyverse风格写法:
library(dplyr) target_ids <- df %>% group_by(ID) %>% summarise( # 确认患者同时患过疾病1和2 has_1 = any(Disease == 1), has_2 = any(Disease == 2), # 取第一次患疾病1的就诊时间,最后一次患疾病2的就诊时间 first_1_time = min(Visit[Disease == 1], Inf), last_2_time = max(Visit[Disease == 2], -Inf), # 核心条件:疾病1的首次就诊早于疾病2的末次就诊 passes = has_1 & has_2 & (first_1_time < last_2_time) ) %>% filter(passes) %>% pull(ID) # 查看结果 target_ids # 输出:[1] 2 4 6
解决方案2:基础R实现
如果不想依赖第三方包,用基础R也能完成:
# 按ID拆分数据集 id_groups <- split(df, df$ID) # 逐个检查每个患者的就诊记录 valid_ids <- sapply(id_groups, function(patient_data) { diseases <- patient_data$Disease # 先排除只患一种疾病的情况 if (!any(diseases == 1) || !any(diseases == 2)) return(FALSE) # 找到第一个疾病1和最后一个疾病2的位置 first_1_pos <- which(diseases == 1)[1] last_2_pos <- tail(which(diseases == 2), 1) # 判断顺序是否符合要求 first_1_pos < last_2_pos }) # 提取符合条件的ID target_ids <- as.numeric(names(valid_ids)[valid_ids]) target_ids # 输出:[1] 2 4 6
逻辑说明
两种方法的核心逻辑一致:
- 先排除只患疾病1或只患疾病2的患者
- 只要患者的首次疾病1就诊时间早于末次疾病2就诊时间,就满足筛选要求——中间即使出现疾病3,也不影响这个顺序判断
内容的提问来源于stack exchange,提问作者Jenn0804
相关产品推荐
相关产品推荐

