You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现含缺失id键的非典型full_join()合并?

如何在dplyr的full_join中保留id为NA的独立行

当使用full_join()以id为键合并数据时,默认会将所有id=NA的记录视为匹配项合并在一起,无法保留这些NA行的独立性。要实现让每个id为NA的记录都作为独立行保留,可以通过给NA行分配唯一临时键的方式解决,具体步骤如下:

解决方案思路

  1. 为两个数据框中的NA行生成唯一的临时标识,确保不同数据框的NA行、同一数据框的不同NA行都有唯一键;
  2. 以临时标识为键执行full_join(),此时NA行因键唯一会被当作独立行处理;
  3. 合并后将临时标识恢复为原始的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 09:15:09