在R中合并含缺失值的数据集:多ID列匹配与缺失值补全
解决多键含缺失值的 tibble 左连接与缺失值补全问题
问题描述
需要以df1为主表,与df2执行左连接,满足以下要求:
- 优先通过
issn字段匹配,匹配失败时再使用journal_title字段; - 合并后利用两个数据集的非缺失值补全
journal_title、issn列的缺失值,并获取rank字段信息。
模拟数据
df1 <- tibble(journal_title = c(NA, "Journal of yyy", "Journal of zzz"), issn = c(9999, 1234, NA)) df2 <- tibble(journal_title = c("Journal of xxx", NA, "Journal of zzz"), issn = c(9999, 1234, 8888), rank = c(1,2,3))
目标结果
df3 <- tibble(journal_title = c("Journal of xxx", "Journal of yyy", "Journal of zzz"), issn = c(9999, 1234, 8888), rank = c(1,2,3))
解决方案
可以通过分步连接+缺失值合并的方式实现需求,以下提供两种可行方案:
方案一:分步连接后合并结果
核心思路是先通过issn完成匹配,再对未匹配的行用journal_title补连,最后合并补全缺失值:
library(dplyr) # 1. 通过issn左连接,标记匹配类型 join_issn <- df1 %>% left_join(df2, by = "issn", suffix = c("_df1", "_df2")) %>% mutate(match_type = ifelse(!is.na(rank), "issn", NA)) # 2. 提取未匹配行,通过journal_title左连接 join_title <- join_issn %>% filter(is.na(match_type)) %>% select(journal_title_df1, issn_df1) %>% rename(journal_title = journal_title_df1, issn = issn_df1) %>% left_join(df2, by = "journal_title", suffix = c("_df1", "_df2")) %>% mutate(match_type = "title") # 3. 合并结果并补全缺失值 result <- bind_rows(join_issn %>% filter(!is.na(match_type)), join_title) %>% mutate( journal_title = coalesce(journal_title_df1, journal_title_df2), issn = coalesce(issn_df1, issn_df2) ) %>% select(journal_title, issn, rank) # 查看结果 result
方案二:嵌套连接+直接补全(更紧凑)
通过两次左连接分别获取issn和journal_title匹配的结果,再用coalesce优先保留优先级高的匹配值:
library(dplyr) result <- df1 %>% # 第一次连接:通过issn匹配 left_join(df2, by = "issn", suffix = c("", "_issn")) %>% # 第二次连接:为未匹配行补充journal_title匹配的rank left_join(df2 %>% select(journal_title, rank_title = rank), by = "journal_title") %>% # 补全各字段:优先取issn连接结果,再取title连接结果 mutate( journal_title = coalesce(journal_title, journal_title_issn), issn = coalesce(issn, issn_issn), rank = coalesce(rank, rank_title) ) %>% # 保留目标列 select(journal_title, issn, rank) # 查看结果 result
两种方案执行后均会输出与目标df3完全一致的结果。
内容的提问来源于stack exchange,提问作者T. C. Nobel
相关产品推荐
相关产品推荐

