R中的"不加入"

tan*_*ach 4 merge r inner-join outer-join data.table

我正在寻找一种快速的方法来做"不加入"(即保持不合并的行,或内部联接的反向).我一直在做的方法是使用data.table for X和Y,然后设置key.例如:

require(data.table)

X <- data.table(category = c('A','B','C','D'), val1 = c(0.2,0.3,0.8,0.7))
Y <- data.table(category = c('B','C','D','E'), val2 = c(2,3,5,7))
XY <- merge(X,Y,by='category')

> XY
   category val1 val2
1:        B  0.3    2
2:        C  0.8    3
3:        D  0.7    5
Run Code Online (Sandbox Code Playgroud)

但我需要反过来,所以我必须这样做:

XY_All <- merge(X,Y,by='category',all=TRUE)
setkey(XY,category)
setkey(XY_All,category)
notXY <- XY_All[!XY]    #data.table not join (finally)

> notXY
   category val1 val2
1:        A  0.2   NA
2:        E   NA    7
Run Code Online (Sandbox Code Playgroud)

我觉得这很长篇大论(特别是来自data.frame).我错过了什么吗?

编辑:我在考虑了更多关于不加入之后得到了这个

X <- data.table(category = c('A','B','C','D'), val1 = c(0.2,0.3,0.8,0.7),key = "category")
Y <- data.table(category = c('B','C','D','E'), val2 = c(2,3,5,7), key = "category")
notXY <- merge(X[!Y],Y[!X],all=TRUE)
Run Code Online (Sandbox Code Playgroud)

但WheresTheAnyKey在下面的回答更清晰.最后一个障碍是预置data.table键,不必这样做是很好的.

编辑:澄清一下,接受的解决方案是:

merge(anti_join(X, Y, by = 'category'),anti_join(Y, X, by = 'category'), by = 'category', all = TRUE)
Run Code Online (Sandbox Code Playgroud)

sta*_*kam 5

require(dplyr)
rbind_list(anti_join(X, Y), anti_join(Y, X))
Run Code Online (Sandbox Code Playgroud)

编辑:既然有人要求解释,这是发生了什么:

第一个anti_join()函数返回X没有匹配行的行,Y匹配由连接的连接确定.第二个反过来. rbind_list()只需获取其输入的结果,并将其tbl与每个输入的所有观察结果组合成一个单独的替换缺失的可变数据NA.

  • 不这样做.要使用anti_join获得预期的结果,你需要`merge(anti_join(X,Y,by ='category'),anti_join(Y,X,by ='category'),by ='category',all = TRUE)` (3认同)

Mik*_*han 5

setkey(X,category)
setkey(Y,category)

rbind(X[!Y], Y[!X], fill = TRUE)
Run Code Online (Sandbox Code Playgroud)

  • 好点子.刚改变了 此解决方案不涉及笛卡尔连接. (2认同)