如何基于多条件合并两个DataFrame以匹配患者治疗与检测数据?
问题分析与解决
问题背景
需要合并两个DataFrame以匹配患者生物检测时的对应治疗方案:
data.frame1:存储患者就诊记录,包含ID、就诊日期Date1、就诊次数Num_Visit、治疗方案Treatmentdata.frame2:存储患者生物检测记录,包含ID、检测日期Date2、就诊次数、生物指标Gly
已知两表的Num_Visit无法直接匹配,原尝试代码未得到预期结果:
result <- data.frame1 %>% left_join(data.frame2, by = "ID") %>% group_by(ID, Date1) %>% filter(between(Date2, lag(Date1), lead(Date1, default = last(Date1)))) %>% summarise(Gly = first(Gly))
期望输出格式如下:
data.frame3 <- data.frame( ID = c(1, 1, 2, 2, 2, 3, 3, 3), Date2 = c(1, 8, 20, 24, 34, 25, 41, 57), Num_Visit = c(1, 2, 1, 2, 3, 1, 2, 3), Gly = c(1.1, 1.3, 1.1, 0.9, 1.4, 1.0, 1.8, 0.8), Treatment = c("A", "B", "E", "A", "A", "D", "C", "E") )
原代码问题
原代码核心逻辑错误在于分组方式:按ID和Date1分组后,每个分组仅对应单次就诊记录,无法关联患者所有检测日期;同时lag(Date1)和lead(Date1)在该分组下无法生成有效时间区间,导致筛选逻辑失效。
解决方案
以下提供两种基于dplyr的可靠实现方式,确保每个检测日期匹配到对应治疗方案:
方法1:时间区间匹配法
先为每条就诊记录生成有效区间(当前就诊日期至下一次就诊日期),再将检测日期匹配至对应区间:
library(dplyr) # 预处理就诊表:生成每个就诊的结束时间(下一次就诊日期,最后一次设为无穷大) df1_processed <- data.frame1 %>% arrange(ID, Date1) %>% group_by(ID) %>% mutate(next_Date1 = lead(Date1, default = Inf)) %>% ungroup() # 匹配检测日期到对应就诊区间 result <- data.frame2 %>% arrange(ID, Date2) %>% left_join(df1_processed, by = "ID") %>% # 筛选处于当前就诊区间内的检测记录 filter(Date2 >= Date1 & Date2 < next_Date1) %>% # 整理为期望输出格式 select(ID, Date2, Num_Visit = Num_Visit.y, Gly, Treatment) %>% arrange(ID, Date2)
方法2:最近就诊匹配法
找到每个检测日期之前的最近一次就诊记录,直接匹配该就诊对应的治疗方案:
library(dplyr) library(fuzzyjoin) result <- data.frame2 %>% arrange(ID, Date2) %>% # 模糊匹配:ID相同,且检测日期晚于/等于就诊日期 fuzzy_left_join( data.frame1 %>% arrange(ID, Date1), by = c("ID" = "ID", "Date2" = "Date1"), match_fun = list(`==`, `>=`) ) %>% group_by(ID, Date2) %>% # 保留每个检测日期对应的最近一次就诊记录 filter(Date1 == max(Date1)) %>% ungroup() %>% # 整理为期望输出格式 select(ID, Date2, Num_Visit = Num_Visit.x, Gly, Treatment) %>% arrange(ID, Date2)
注意事项
- 确保
Date1和Date2为日期类型或可比较的数值类型,若为字符型需先转换:as.Date(Date1, format = "%Y-%m-%d")(根据实际日期格式调整) - 两种方法最终输出结构与
data.frame3完全一致,可根据数据规模选择:方法1效率更高,方法2逻辑更直观
内容的提问来源于stack exchange,提问作者Jilano
相关产品推荐
相关产品推荐

