如何基于多列匹配从另一数据框填充df1中的NA值(R语言)
解决方案
问题根源
你用left_join后出现重复行,是因为df2中存在Name、Surname、DOB三列的组合不唯一(同一组姓名+生日对应多个ID),导致匹配后每一个重复ID都会对应df1的一行,最终行数增加。
步骤1:清理df2,确保匹配组合唯一
首先要确保df2里每个(Name, Surname, DOB)组合只对应一个ID。先检查重复项,再去重:
library(dplyr) # 检查df2中是否有重复的匹配组合 df2_duplicates <- df2 %>% group_by(Name, Surname, DOB) %>% filter(n() > 1) # 若存在重复,保留每个组合的第一个ID(可根据实际需求调整规则) df2_clean <- df2 %>% distinct(Name, Surname, DOB, .keep_all = TRUE)
步骤2:填充df1的缺失ID
推荐两种简洁方法,均不会增加行数:
方法一:用rows_update(dplyr 1.0.0及以上版本)
直接匹配更新缺失值,逻辑更直观:
df1_filled <- df1 %>% rows_update( df2_clean %>% select(Name, Surname, DOB, `ID Number`), by = c("Name", "Surname", "DOB"), unmatched = "ignore" )
by指定匹配的三列unmatched = "ignore"表示只更新能匹配上的行,不处理无匹配的行
方法二:用left_join + coalesce(兼容旧版dplyr)
先关联再合并值,适合版本较低的环境:
df1_filled <- df1 %>% left_join(df2_clean, by = c("Name", "Surname", "DOB"), suffix = c("", "_df2")) %>% mutate(`ID Number` = coalesce(`ID Number`, `ID Number_df2`)) %>% select(-`ID Number_df2`)
coalesce会优先取df1原有的ID,原ID为NA时才用df2的ID- 最后删除关联后新增的冗余列
额外注意事项
确保三列数据类型完全一致,比如DOB列要统一为Date类型,避免因格式不匹配导致无法正确关联:
# 转换为Date类型(根据你的原始格式调整format参数) df1$DOB <- as.Date(df1$DOB, format = "%Y-%m-%d") df2$DOB <- as.Date(df2$DOB, format = "%Y-%m-%d")
内容的提问来源于stack exchange,提问作者raven123
相关产品推荐
相关产品推荐

