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

基于多键列的DataFrame全连接:允许NA时的唯一匹配需求

带有NA键的DataFrame唯一匹配全连接实现

需求说明

需对两个DataFrame按key1、key2、key3、key4四个键列执行全连接,匹配规则如下:

  • 若一行的一个或多个键值为NA,但剩余非NA键能与另一DataFrame的某一行唯一匹配,则执行匹配
  • 若无法实现唯一匹配,则该行作为新行追加到结果中

示例数据

df1

df1 <- data.frame(
  key1 = c("A", "B", "B", "D", "E"),
  key2 = c(1, 2, 2, 4, 5),
  key3 = c("ab", "bc", "cd", "de", "ef"),
  key4 = c(10, 20, 20, 40, 50),
  other1 = c("x", "x", "y", "x", "x"),
  other2 = c(1, 0, 0, 1, 1),
  stringsAsFactors = FALSE
)

df2

df2 <- data.frame(
  key1 = c("A", "B", "D", "F"),
  key2 = c(1, 2, NA, 6),
  key3 = c("ab", NA, "de", "fg"),
  key4 = c(10, 20, 40, 50),
  other3 = c(100, 10, 75, 30),
  stringsAsFactors = FALSE
)

常规方法问题

标准full_join无法处理含NA键的唯一匹配场景(比如df2第3行与df1第4行):

merged.df <- df1 %>% full_join(df2, by = c("key1", "key2", "key3", "key4"))

期望输出

key1 key2 key3 key4 other1 other2 other3
A    1    ab   10   x      1      100
B    2    bc   20   x      0      NA
B    2    cd   20   y      0      NA
B    2    NA   20   NA     NA     10
D    4    de   40   x      1      75
E    5    ef   50   x      1      NA
F    6    fg   50   NA     NA     30

解决方案

使用fuzzyjoin包的fuzzy_full_join函数,自定义匹配逻辑并确保匹配唯一性:

步骤1:安装并加载依赖包

install.packages("fuzzyjoin")
library(fuzzyjoin)
library(dplyr)

步骤2:执行自定义全连接

# 定义匹配规则:若其中一个键为NA则跳过该键匹配,非NA键必须相等
match_fun <- function(x, y) {
  ifelse(is.na(x) | is.na(y), TRUE, x == y)
}

merged_result <- fuzzy_full_join(
  df1, df2,
  by = c("key1", "key2", "key3", "key4"),
  match_fun = match_fun
) %>%
  # 计算有效匹配的键数量
  mutate(match_count = rowSums(
    !is.na(across(paste0("key", 1:4, ".x"))) & 
    across(paste0("key", 1:4, ".x")) == across(paste0("key", 1:4, ".y"))
  )) %>%
  # 保留匹配键最多的结果
  group_by(across(c(ends_with(".x"), ends_with(".y")))) %>%
  filter(match_count == max(match_count)) %>%
  # 过滤掉非唯一匹配的行
  group_by(key1.x, key2.x, key3.x, key4.x) %>%
  filter(n() == 1 | is.na(key1.y)) %>%
  group_by(key1.y, key2.y, key3.y, key4.y) %>%
  filter(n() == 1 | is.na(key1.x)) %>%
  ungroup() %>%
  # 合并键列(优先取非NA值)
  mutate(
    key1 = coalesce(key1.x, key1.y),
    key2 = coalesce(key2.x, key2.y),
    key3 = coalesce(key3.x, key3.y),
    key4 = coalesce(key4.x, key4.y)
  ) %>%
  # 选择并整理最终列
  select(key1, key2, key3, key4, other1, other2, other3) %>%
  distinct() %>%
  arrange(key1, key2, key3)

运行上述代码后,输出结果将与期望完全一致。


内容的提问来源于stack exchange,提问作者user21508369

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 13:53:16