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

如何按record_id和event_name合并数据表?解决merge重复列问题

问题描述

现有数据表结构如下:

record_idevent_namelab_value_1lab_value_2lab_value_3lab_value_4
ID 1t00.10.10.10.1
ID 2t10.20.20.20.2
ID 2t20.30.30.3NA

需要合并三类外部数据集:

  • A) 补充现有记录缺失值
record_idevent_namelab_value_1lab_value_2lab_value_3lab_value_4
ID 2t2NANANA0.5
  • B) 新增record_id
record_idevent_namelab_value_1lab_value_2lab_value_3lab_value_4
ID 3t00.10.20.30.5
  • C) 为现有记录新增时间点
record_idevent_namelab_value_1lab_value_2lab_value_3lab_value_4
ID 2t30.10.20.30.5

重要提示:不同数据框的列顺序可能不同!

需求:当record_id和event_name同时匹配时,用新数据填补旧数据的缺失值;不匹配时新增行。使用merge函数后出现了重复列(如lab_ldl.x、lab_ldl.y),未实现合并到原列的效果,测试示例如下:

old_data
  record_id redcap_event_name lab_ldl lab_ggt lab_cpept lab_alat lab_asat lab_hba1c
1 ADI757106          t3_arm_1    0.12    0.51        NA       NA       NA        NA
2 ADI123456          t1_arm_1      NA      NA     0.133    0.155     47.3        NA

new_data
  record_id redcap_event_name lab_ldl lab_hba1c
1 ADI123456          t1_arm_1       1         5

merge(old_data, new_data, by = c("record_id", "redcap_event_name"), all = TRUE, sort = TRUE)

  record_id redcap_event_name lab_ldl.x lab_ggt lab_cpept lab_alat lab_asat lab_hba1c.x lab_ldl.y lab_hba1c.y
1 ADI123456          t1_arm_1        NA      NA     0.133    0.155     47.3          NA         1           5
2 ADI757106          t3_arm_1      0.12    0.51        NA       NA       NA          NA        NA          NA
解决方案

方法1:Base R 实现

先合并数据,再对重复列进行合并,保留非NA值:

# 合并数据
merged_data <- merge(old_data, new_data, by = c("record_id", "redcap_event_name"), all = TRUE)

# 获取所有非合并键的列名,提取原始列前缀
non_key_cols <- setdiff(colnames(merged_data), c("record_id", "redcap_event_name"))
original_cols <- unique(sub("\\.(x|y)$", "", non_key_cols))

# 遍历每个原始列,合并x和y列的非NA值
for(col in original_cols) {
  merged_data[[col]] <- ifelse(is.na(merged_data[[paste0(col, ".x")]]), merged_data[[paste0(col, ".y")]], merged_data[[paste0(col, ".x")]])
  # 删除临时的x和y列
  merged_data[c(paste0(col, ".x"), paste0(col, ".y"))] <- NULL
}

# 查看结果
merged_data

方法2:tidyverse 工具包实现

用dplyr的bind_rows结合group_by和coalesce更简洁,自动处理列顺序问题:

library(dplyr)

# 合并数据并按分组键聚合,用coalesce填补NA
merged_data <- bind_rows(old_data, new_data) %>%
  group_by(record_id, redcap_event_name) %>%
  summarise(across(everything(), ~coalesce(!!!.)), .groups = "drop")

# 查看结果
merged_data

方法说明

  • bind_rows会自动对齐列,不管列顺序如何,缺失的列会补NA
  • group_by(record_id, redcap_event_name)把相同记录的行分组
  • across(everything(), ~coalesce(!!!.))对每一列,用coalesce函数取第一个非NA值,实现缺失值填补

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 18:32:15