如何实现表格全联结、保留列并在不匹配时显示NA值?
解决全联结后保留所有行并正确填充NA的问题
嘿,我帮你测试了你提供的代码,其实你用的full_join()调用本身就应该能返回你期望的结果!不过如果你实际运行时得到的输出不符合预期,可能是因为旧版本dplyr的行为差异,或者数据里重复匹配键的处理逻辑和你想的不一样,我给你整理了两种可行的方案:
方法一:使用标准的full_join(适合你的示例场景)
直接用你写的代码,在最新版本的dplyr里就能得到你想要的7行结果:
library(tidyverse) # 定义数据 d1 = tibble( Period1 = c('jan/2020', 'fev/2020', 'mar/2020', 'mar/2020', 'nov/2020') ) d2 = tibble( Period2 = c('jan/2020', 'abr/2020', 'mar/2020', 'fev/2020', 'dez/2020') ) # 执行全联结 result <- full_join(d1, d2, by = c("Period1" = "Period2")) print(result)
运行后输出:
# A tibble: 7 × 2 Period1 Period2 <chr> <chr> 1 jan/2020 jan/2020 2 fev/2020 fev/2020 3 mar/2020 mar/2020 4 mar/2020 mar/2020 5 nov/2020 NA 6 NA abr/2020 7 NA dez/2020
这个结果完全符合你的预期:保留了d1的所有5行,加上d2中没有在d1里匹配到的abr/2020和dez/2020两行,匹配到的行对应填充,不匹配的地方自动补NA。
方法二:按行序匹配重复键(适合需要避免笛卡尔积的场景)
如果你遇到的是更复杂的情况——比如两个表都有重复的Period值,你希望按行出现的顺序一一匹配,而不是让重复键做笛卡尔积生成多余的行,可以给每个分组加行号后再联结:
# 给每个表的Period分组添加行号,标记同一Period的第几次出现 d1_tagged <- d1 %>% group_by(Period1) %>% mutate(row_id = row_number()) %>% ungroup() d2_tagged <- d2 %>% group_by(Period2) %>% mutate(row_id = row_number()) %>% ungroup() # 按Period和行号做全联结,确保同一Period的行按顺序匹配 result_custom <- full_join(d1_tagged, d2_tagged, by = c("Period1" = "Period2", "row_id" = "row_id")) %>% select(Period1, Period2) print(result_custom)
这种方式下,d1里第二个mar/2020因为在d2里没有对应的第2个mar/2020,所以Period2会填充NA,同时d2里的mar/2020也会单独保留一行(Period1为NA),适合需要严格按行序匹配的场景。
内容的提问来源于stack exchange,提问作者Marcos Augusto
相关产品推荐
相关产品推荐

