如何实现含缺失id键的非典型full_join()合并?
如何在dplyr的full_join中保留id为NA的独立行
当使用full_join()以id为键合并数据时,默认会将所有id=NA的记录视为匹配项合并在一起,无法保留这些NA行的独立性。要实现让每个id为NA的记录都作为独立行保留,可以通过给NA行分配唯一临时键的方式解决,具体步骤如下:
解决方案思路
- 为两个数据框中的NA行生成唯一的临时标识,确保不同数据框的NA行、同一数据框的不同NA行都有唯一键;
- 以临时标识为键执行
full_join(),此时NA行因键唯一会被当作独立行处理; - 合并后将临时标识恢复为原始的NA值,整理得到目标结果。
具体代码实现
library(dplyr) # 原始数据 df1 <- data.frame(id = c(1, 2, 3, NA, NA, NA), t1 = c(1, 2, 3, 4, 5, 6)) df2 <- data.frame(id = c(1, 2, 3, NA, NA, 4), t2 = c(1, 2, 3, 4, NA, 5)) # 步骤1:生成唯一临时键 # df1的NA行用行号作为临时键,非NA行保留原id df1_temp <- df1 %>% mutate(temp_id = case_when( !is.na(id) ~ id, TRUE ~ row_number() )) # df2的NA行用「df1行数 + 自身行号」作为临时键,避免和df1的NA键重复 df2_temp <- df2 %>% mutate(temp_id = case_when( !is.na(id) ~ id, TRUE ~ row_number() + nrow(df1) )) # 步骤2:以临时键执行full_join result_temp <- full_join(df1_temp, df2_temp, by = "temp_id") # 步骤3:恢复原始id并整理结果 result <- result_temp %>% # 合并两个id列,非NA值一致,NA值取任意即可 mutate(id = coalesce(id.x, id.y)) %>% # 保留需要的列 select(id, t1, t2) %>% # 排序:非NA的id在前,按id升序;NA行在后,和预期输出对齐 arrange(ifelse(is.na(id), 1, 0), id) print(result)
输出结果
id t1 t2 1 1 1 1 2 2 2 2 3 3 3 3 4 4 NA 5 5 NA 4 NA 6 NA 5 NA 7 NA 6 NA 8 NA NA 4 9 NA NA NA
原理说明
默认的full_join()会将NA视为可匹配的键,导致所有id=NA的行被合并。通过为每个NA行分配唯一临时键,相当于给这些行打上了独特的标签,full_join()会将它们当作不同的匹配组,从而保留原始的独立行结构,最后再将临时键还原为NA即可得到预期结果。
内容的提问来源于stack exchange,提问作者D. Studer
相关产品推荐
相关产品推荐

