如何在dplyr中排除指定列进行连接操作?
基于排除指定列的数据集anti-join操作方法
问题场景
有两个列结构完全相同的数据集,需要基于除z和a之外的所有列执行anti-join操作,但直接使用join_by(-c(z, a))会报错:
library(dplyr) df1 <- tibble(x = c("A", "B", "C"), y = c("X", "Y", "Z"), z = c(1, 2, 3), a = c(4, 5, 6)) df2 <- tibble(x = c("A", "D", "E"), y = c("X", "W", "R"), z = c(1, 5, 6), a = c(4, 7, 8)) df2 %>% anti_join(df1, join_by(-c(z, a))) #> Error in `join_by()`: #> ! Expressions must use one of: `==`, `>=`, `>`, `<=`, `<`, `closest()`, #> `between()`, `overlaps()`, or `within()`. #> ℹ Expression 1 is `-c(z, a)`.
解决方案
方法1:生成目标列名向量传给by参数
join_by不支持直接的tidy-select语法,但可以先通过tidyselect逻辑获取需要连接的列名,再传给anti_join的by参数:
# 获取除z、a外的所有列名 join_cols <- df1 %>% select(-z, -a) %>% names() # 或者用setdiff:join_cols <- setdiff(names(df1), c("z", "a")) df2 %>% anti_join(df1, by = join_cols)
运行结果:
# A tibble: 2 × 4 x y z a <chr> <chr> <dbl> <dbl> 1 D W 5 7 2 E R 6 8
方法2:在join_by中结合across(dplyr 1.1.0+)
如果偏好使用join_by语法,可以结合across实现tidy-select的列排除逻辑:
df2 %>% anti_join(df1, join_by(across(-c(z, a))))
该写法直接在join_by内通过across(-c(z, a))指定连接列,无需单独生成列名向量,代码更简洁。
说明
join_by本身不支持直接的-c(col1, col2)这类排除语法,但across可以在join_by中兼容tidy-select规则,实现列选择/排除。- 两种方法都能实现“基于除指定列外的所有列做anti-join”的需求,可根据个人习惯选择。
内容的提问来源于stack exchange,提问作者Alberto Agudo Dominguez
相关产品推荐
相关产品推荐

