评估一个data.table是否是另一个的子集的简单方法?

时间:2016-02-21 03:23:21

标签: r data.table

我希望避免编写一个函数来检测一个data.table的所有行是否存在于R中的另一个data.table中。例如:

library(data.table)
t1=data.table(a=c(1,2,3,4,5), b=c(1,2),d=c(5,6,7,8,9))
t2=data.table(x=c(2,3),x2=c(2,1),x3=c(6,7))
t3=data.table(y1=c(2,4), y2=c(2,2), y3=c(6,8))

我想要这个函数(再次,最好是data.table可以很容易地做,但如果不是那样也可以)t2和t3都返回TRUE。

1 个答案:

答案 0 :(得分:5)

一种方法是使用连接并检查所有元素的相等性:

nms <- names(t2)
all(t1[t2, on=c(a=nms[1], b=nms[2], d=nms[3])] == t2, nomatch = 0L)

或使用密钥加入:

setkey(t1)
# setkey(t2) not absolutely necessary

all(t1[t2, nomatch = 0L] == t2)
#[1] TRUE

如果您已加载intersect,也可以使用dplyr(感谢@Frank)。

library(dplyr)
all(intersect(unname(t2), unname(t1)) == t2)
# alternatively: 
# all(intersect(t1, setNames(t2, names(t1))) == t2)
#[1] TRUEd
all(intersect(unname(t3), unname(t1)) == t3)
# alternatively: 
# all(intersect(t1, setNames(t3, names(t1))) == t3)
#[1] TRUE

如果t2与t1和t2的交点大小不同,上面会抛出错误。在这种情况下,以下内容将返回FALSE而不是错误。

dim(intersect(t1, setNames(t2, names(t1))))[1] == dim(t2)[1]
#[1] TRUE
dim(intersect(t1, setNames(t3, names(t1))))[1] == dim(t3)[1]
#[1] TRUE

请注意,这些答案取决于订单,如果您的情况需要,您可能需要重新订购以解决此问题。