R语言按指定匹配键合并两个行数不同数据框 匹配替换未匹配保留原值
R 双列键值匹配合并数据表实现方案
需求核心:保留全量表df1的所有行结构,以num、lab为联合匹配键,和子集表df2匹配成功的行取df2的val值,匹配失败的行保留df1原有的val值。
方法1:dplyr 实现(代码可读性最高)
通过左连接保留df1全量行,再用非空填充函数优先取df2的值:
library(dplyr) df3 <- df1 %>% # 以num、lab为键左连接,给两个表的val列加后缀区分 left_join(df2, by = c("num", "lab"), suffix = c("_df1", "_df2")) %>% # 优先取df2的val,为空则取df1原val mutate(val = coalesce(val_df2, val_df1)) %>% # 保留需要的列 select(num, lab, val)
方法2:base R 原生实现(无需安装第三方包)
通过键值匹配直接做赋值替换,适合不想额外装包的场景:
# 拼接双列生成唯一匹配键 df1_key <- paste(df1$num, df1$lab, sep = "|") df2_key <- paste(df2$num, df2$lab, sep = "|") # 查找df1每行在df2中的匹配位置 match_loc <- match(df1_key, df2_key) # 复制df1作为结果基础 df3 <- df1 # 匹配成功的行替换为df2的val值 df3$val[!is.na(match_loc)] <- df2$val[match_loc[!is.na(match_loc)]]
方法3:data.table 实现(大数据量性能最优)
适合十万行以上的大数据集,运行速度远高于前两种方法:
library(data.table) # 转data.table格式 setDT(df1) setDT(df2) # 右连接保留df1全量行,优先取df2的val df3 <- df2[df1, on = .(num, lab)][ , .(num, lab, val = fcoalesce(val, i.val)) ]
运行以上任意一种方法,得到的结果都和预期df3完全一致:
num lab val 1 1 A 10 2 1 B 10 3 1 C 0 4 2 A 10 5 2 B 0 6 2 C 0所有方法均为按键值精准匹配,不需要提前对表排序,不会出现行错位问题。
内容的提问来源于stack exchange,提问作者trilisser
相关产品推荐
相关产品推荐

