R语言用dplyr的join合并数据框如何避免重复填充匹配值?
实现方案
你需要的匹配逻辑是每个v1分组仅第一条记录匹配df2对应的v4值,同分组其余记录不匹配返回NA,可以通过dplyr自带函数实现,两种常用实现方式如下:
方式1:连接后按分组修改v4值
该方法代码最简洁,适合确定仅需要保留分组第一行匹配值的场景:
library(dplyr) # 原数据 v1 = c("a", "a", "b", "b", "c", "c") v2 = c(1,2,3,4,3,4) v3 = c("a", "b", "c") v4 = c(10,20,30) df1 = data.frame(v1, v2) df2 = data.frame(v3, v4) # 实现逻辑:先正常连接,再按v1分组,仅保留第一行的v4值,其余置为NA result <- left_join(df1, df2, by = c("v1" = "v3")) %>% group_by(v1) %>% mutate(v4 = if_else(row_number() == 1, v4, NA_real_)) %>% ungroup()
运行后输出结果:
> print(result) # A tibble: 6 × 3 v1 v2 v4 <chr> <dbl> <dbl> 1 a 1 10 2 a 2 NA 3 b 3 20 4 b 4 NA 5 c 3 30 6 c 4 NA
方式2:新增组内行号作为联合连接键
该方法适合后续还有其他多条件匹配需求的场景,扩展灵活性更高:
library(dplyr) # 给df1按v1分组新增组内行号 df1_rn <- df1 %>% group_by(v1) %>% mutate(rn = row_number()) %>% ungroup() # 给df2按v3分组新增组内行号(每个分组仅1条,所以rn均为1) df2_rn <- df2 %>% group_by(v3) %>% mutate(rn = row_number()) %>% ungroup() # 用v1/v3 + rn作为联合键连接,仅第一行能匹配到v4值 result <- left_join(df1_rn, df2_rn, by = c("v1" = "v3", "rn" = "rn")) %>% select(-rn)
运行输出结果和方式1完全一致。
内容的提问来源于stack exchange,提问作者Willem. R. Nieuwenhuis
相关产品推荐
相关产品推荐

