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

R语言基于n_pz与日期范围实现内连接、左连接合并数据集

错误原因分析
  • 基础包merge方法问题:第一次合并后未匹配到检查记录的行buffer_date为NA,日期逻辑判断返回NA会被subset直接过滤,导致中间结果s仅保留匹配成功的行,后续二次merge属于多余操作,也无法实现保留所有db_1记录的需求。
  • dplyr方法问题:left_join的by参数仅支持等值连接的字段匹配,不能直接写入不等值判断逻辑,你输入的逻辑表达式直接返回了布尔值FALSE,因此会提示找不到FALSE字段。
正确实现方案

1. 不等值连接(左连接+内连接)

dplyr版本(推荐,1.1.0及以上版本支持join_by语法)

library(dplyr)
fmt <- "%d/%m/%Y"
# 统一转换日期格式
db_11 <- transform(db_1, 
                   admission_date = as.Date(admission_date, fmt),
                   discharge_date = as.Date(discharge_date, fmt))
db_21 <- transform(db_2, 
                   buffer_date = as.Date(buffer_date, fmt))

# 左连接:保留所有db_1的住院患者,仅匹配住院期间的检查记录
left_result <- left_join(
  db_11, 
  db_21,
  join_by(n_pz, buffer_date >= admission_date, buffer_date <= discharge_date)
)

# 内连接:仅保留住院期间有对应检查记录的患者
inner_result <- inner_join(
  db_11, 
  db_21,
  join_by(n_pz, buffer_date >= admission_date, buffer_date <= discharge_date)
)

如果使用旧版dplyr无join_by功能,可采用先等值连接再过滤的方式:

# 旧版dplyr左连接实现
left_result <- left_join(db_11, db_21, by = "n_pz") %>%
  filter((buffer_date >= admission_date & buffer_date <= discharge_date) | is.na(buffer_date))

# 旧版dplyr内连接实现
inner_result <- inner_join(db_11, db_21, by = "n_pz") %>%
  filter(buffer_date >= admission_date & buffer_date <= discharge_date)

基础包版本

fmt <- "%d/%m/%Y"
db_11 <- transform(db_1, 
                   admission_date = as.Date(admission_date, fmt),
                   discharge_date = as.Date(discharge_date, fmt))
db_21 <- transform(db_2, 
                   buffer_date = as.Date(buffer_date, fmt))

# 左连接实现
merge_raw_left <- merge(db_11, db_21, by = "n_pz", all.x = TRUE)
left_result <- merge_raw_left[with(merge_raw_left, 
  (buffer_date >= admission_date & buffer_date <= discharge_date) | is.na(buffer_date)), ]

# 内连接实现
merge_raw_inner <- merge(db_11, db_21, by = "n_pz")
inner_result <- merge_raw_inner[with(merge_raw_inner, 
  buffer_date >= admission_date & buffer_date <= discharge_date), ]

2. 多检查记录转宽表

使用tidyr的pivot_wider实现,同一患者的多条检查会按顺序生成buffer_date_1、buffer_result_1、buffer_date_2、buffer_result_2这类列,无检查记录的患者对应检查字段为NA:

library(tidyr)
wide_result <- left_result %>%
  # 按患者分组为每条检查生成序号
  group_by(n_pz) %>%
  mutate(check_seq = row_number()) %>%
  ungroup() %>%
  # 转宽表
  pivot_wider(
    id_cols = c(n_pz, admission_date, discharge_date),
    names_from = check_seq,
    values_from = c(buffer_date, buffer_result),
    names_sort = TRUE
  )

内容的提问来源于stack exchange,提问作者ArTu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 19:54:08