You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于多条件合并两个DataFrame以匹配患者治疗与检测数据?

问题分析与解决

问题背景

需要合并两个DataFrame以匹配患者生物检测时的对应治疗方案:

  • data.frame1:存储患者就诊记录,包含ID、就诊日期Date1、就诊次数Num_Visit、治疗方案Treatment
  • data.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 16:27:45