R中的“未加入”

问题描述 投票:4回答:5

我正在寻找一种快速的方法来实现“不连接”(即保留未合并的行或内部连接的逆行)。我一直在做的方法是对X和Y使用data.table,然后设置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

但是我需要与此相反,所以我必须做:

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

我觉得这已经困扰了很长时间(尤其是从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)

但是下面WheresTheAnyKey的答案更清楚。最后一个障碍是预设data.table键,不必这样做是很高兴的。

编辑:为了澄清,可接受的解决方案是:

merge(anti_join(X, Y, by = 'category'),anti_join(Y, X, by = 'category'), by = 'category', all = TRUE)
r merge inner-join data.table outer-join
5个回答
5
投票
require(dplyr)
rbind_list(anti_join(X, Y), anti_join(Y, X))

编辑:由于有人要求解释,因此发生了以下情况:

第一个anti_join()函数返回X中没有匹配行的行,而该行中的匹配由联接所连接的对象确定。第二个则相反。 Y只是将其输入的结果放到单个rbind_list()中,并使用每个输入的所有观察结果,用tbl替换丢失的变量数据。


6
投票
NA

4
投票

您可以使它更加简洁:

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

rbind(X[!Y], Y[!X], fill = TRUE)

0
投票

尝试一下。首先,将“ all”合并为“ TRUE”。然后取出所有完整的案例:

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,all = TRUE)[!merge(X,Y)]

0
投票
XY_All <- merge(X,Y,by='category',all=TRUE)
notXY  <- XY_All[!complete.cases(XY_All),]

查看反连接的一种方法是,您需要将X不在Y中的观察结果和Y不在X中的观察结果串联在一起。如上所述,这可以一步完成。

© www.soinside.com 2019 - 2024. All rights reserved.