R语言:如何用目标数据框替换原数据框指定行列子集(含重复ID)
解决方案:用dplyr批量更新匹配行的指定列
针对你的需求,推荐使用dplyr包的rows_update()函数,它专门用于根据匹配键更新数据框中的指定列,完美适配o含重复id、rid唯一的场景,且支持多列扩展。
步骤1:加载依赖包
library(dplyr)
步骤2:执行更新操作
# 定义原始数据 o <- tibble(id = c(2, 3, 4, 7, 10, 2), aa = letters[1:6], bb = LETTERS[2:7], cc = 11:16) r <- tibble(id = c(2,4), cc = c(111, 113), aa = c("aa", "cc")) rv <- c("aa", "cc") # 执行更新:仅更新rv指定的列 updated_o <- rows_update( x = o, y = r %>% select(all_of(c("id", rv))), # 仅保留匹配键id和需要更新的列 by = "id" # 匹配依据为id列 )
结果验证
运行后updated_o的输出如下:
#> # A tibble: 6 × 4 #> id aa bb cc #> <dbl> <chr> <chr> <dbl> #> 1 2 aa B 111 #> 2 3 c C 13 #> 3 4 cc D 113 #> 4 7 e E 15 #> 5 10 f F 16 #> 6 2 aa G 111
可以看到o中所有id为2和4的行,其aa、cc列都被r中的对应值覆盖,重复id的行也被正确更新。
扩展说明
- 多列支持:只需修改
rv向量中的列名,就能批量更新任意数量的列 - 顺序无关:不管
o和r的行列顺序如何,rows_update会自动通过id匹配更新 - 严谨性补充:如果担心
r中存在o没有的id,可以添加unmatched = "ignore"参数忽略这些行(本题中无需此参数,但可增强代码鲁棒性)
备选方法:left_join + 批量替换
如果你更习惯用join的思路,也可以通过以下方式实现:
updated_o2 <- o %>% left_join(r %>% select(all_of(c("id", rv))), by = "id", suffix = c("", "_new")) %>% mutate(across(all_of(rv), ~ coalesce(!!sym(paste0(cur_column(), "_new")), .x))) %>% select(-ends_with("_new"))
该方法先将r的正确列关联到o中,再用coalesce替换旧值,最后清理临时列。
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

