首页 > 解决方案 > 检测“data.table”中行的子集

问题描述

给定两个数据表,a并且b,我如何检查其中的哪些行a也在b?输出应该是一个逻辑向量,长度等于a的行数,并且与 的行顺序相同a,类似于%in%向量。

例如,这是一个简单的、非矢量化的实现。大概有一种更快的方法可以做到这一点。

library(data.table)

dt.in = function(a, b)
    sapply(1 : nrow(a), function(i)
        nrow(fintersect(a[i], b)) > 0)

stopifnot(identical(
   dt.in(
       data.table(
           c1 = c("c", "1", "c", "F", "p", "c", "r"),
           c2 = c("C", "B", "5", "f", "P", "C", "S")),
       data.table(c1 = letters, c2 = LETTERS)),
   c(T, F, F, F, T, T, F)))

标签: rdata.table

解决方案


如果我理解正确,这可以通过加入所有列来实现:

library(data.table)
# sample data 
dt1 <- data.table(
  c1 = c("c", "1", "c", "F", "p", "c", "r"),
  c2 = c("C", "B", "5", "f", "P", "C", "S"))
dt2 <- data.table(c1 = letters, c2 = LETTERS)

stopifnot(identical(names(dt1), names(dt2)))
!is.na(dt2[dt1, on = names(dt1), which = TRUE])
[1]  TRUE FALSE FALSE FALSE  TRUE  TRUE FALSE

评论中,OP 指出列的顺序很重要。为简单起见,我假设两个数据集的列名相同。

which = TRUE要求返回一个行索引向量,该向量在其中或以其他方式df1匹配。根据要求将其转换为逻辑向量。df2NA


如果列名不相同并且匹配仅基于位置,则可以通过编程方式解决,例如

# modified sample data 
dt1 <- data.table(
  c1 = c("c", "1", "c", "F", "p", "c", "r"),
  c2 = c("C", "B", "5", "f", "P", "C", "S"))
dt2 <- data.table(v1 = letters, v2 = LETTERS)

!is.na(dt2[dt1, on = c(paste(names(dt2), names(dt1), sep = "==")), which = TRUE])

请注意, 的列df2现在命名为v1v2而不是c1, c2
连接子句 ( on =) 已成为

"v1==c1" "v2==c2"

推荐阅读