&引用;“不加入”;在R

&引用;“不加入”;在R,r,merge,inner-join,data.table,outer-join,R,Merge,Inner Join,Data.table,Outer Join,我正在寻找一种快速的方法来实现“不连接”(即保留未合并的行,或内部连接的反向)。我一直在做的是使用data.table表示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 <

我正在寻找一种快速的方法来实现“不连接”(即保留未合并的行,或内部连接的反向)。我一直在做的是使用data.table表示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
试试这个。 首先,将“all”设置为“TRUE”进行合并。然后取出所有完整的箱子:

XY_All <- merge(X,Y,by='category',all=TRUE)
notXY  <- XY_All[!complete.cases(XY_All),]
XY\u全部
编辑:
既然有人要求解释,下面是发生的情况:


第一个
anti_join()
函数返回
X
中的行,这些行在
Y
中没有匹配的行,匹配由连接的对象确定。第二种则相反
rbind_list()
只需获取其输入的结果,并将其与来自其每个输入的所有观察值合并成一个
tbl
,将缺少的变量数据替换为
NA

,您可以使其更简洁,如下所示:

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

rbind(X[!Y], Y[!X], fill = 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)]
X

查看反联接的一种方法是,需要将来自X而不是Y的观测值和来自Y而不是X的观测值连接在一起。这可以通过如上所示的一个步骤实现

只有在合并的表的任何其他列中没有任何
NA
值时,这才有效。根据@tanvach的要求,我认为这很好。不幸的是,MrFlick是对的,真正的数据集包含很多NAs。但我喜欢这个解决方案在不设置键的情况下的工作方式,所以请进行投票!现在不是在R-console前,但我相信您应该能够使用类似于
X[!Y]
的东西,但它不是这样工作的。要获得反_连接的预期结果,您需要
merge(反_连接(X,Y,by='category')、反_连接(Y,X,by='category')、by='category',all=TRUE)
Sorry。还有一个步骤:)除了代码之外,还应该包括一个解释,说明您正在做什么以及为什么它会回答这个问题。@azurefrog这是您的解释:)此解决方案不需要1)转换为数据。表2)在合并之前设置键。向你致敬!(尽管如果专门使用data.table,AnyKey的解决方案可能更方便,因为anti_join会将其转换为data.frame)这会将A和E的值压缩为标记为“val1”,而0.2=val1表示A,7=val2表示Egod point。只是换了。这个解决方案不涉及笛卡尔连接。几乎,我喜欢它!我会接受这个优雅的解决方案,如果没有其他人提出另一个没有预设键。
XY_All <- merge(X,Y,by='category',all=TRUE)
notXY  <- XY_All[!complete.cases(XY_All),]
require(dplyr)
rbind_list(anti_join(X, Y), anti_join(Y, X))
setkey(X,category)
setkey(Y,category)

rbind(X[!Y], Y[!X], fill = 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)]
require(dplyr)
notXY = merge(X[!X$category %in% Y$category,], Y[!Y$category %in% X$category,],by = 
"category",all = TRUE)