在data.table中明确选择与另一个data.table中的行匹配的行

时间:2018-03-08 20:12:41

标签: r data.table

给定的两个数据表(tbl_Atbl_B),我想在选择所有的行中的tbl_A,其具有在tbl_B,和我希望代码具有表现力。如果为data.tables定义了%in%运算符,那么这样的事情将是理想的:

subset <- tbl_A[tbl_A %in% tbl_B]

我可以想出很多方法来实现我想要的东西,例如:

# double negation (set differences)
subset <- tbl_A[!tbl_A[!tbl_B,1,keyby=a]]

# nomatch with keyby and this annoying `[,V1:=NULL]` bit
subset <- tbl_B[,1,keyby=.(a=x)][,V1:=NULL][tbl_A,nomatch=0L]

# nomatch with !duplicated() and setnames()
subset <- tbl_B[!duplicated(tbl_B),.(x)][tbl_A,nomatch=0L]; setnames(subset,"x","a")

# nomatch with !unique() and setnames()
subset <- unique(tbl_B)[,.(x)][tbl_A,nomatch=0L]; setnames(subset,"x","a")

# use of a temporary variable (Thanks @Frank)
subset <- tbl_A[, found := FALSE][tbl_B, found := TRUE][(found)][,found:=NULL][]

但每个表达式都难以阅读,乍看之下代码的作用并不明显。有没有更惯用/表达的方式来完成这项任务?

出于示例的目的,这里有一些玩具data.tables:

# toy tables
tbl_A  <- data.table(a=letters[1:5],
                     b=1:5,
                     c=rnorm(5))
tbl_B  <- data.table(x=letters[3:7],
                     y=13:17,
                     z=rnorm(5))
# both tables might have multiple rows with the same key fields.  
tbl_A <- rbind(tbl_A,tbl_A)
tbl_B <- rbind(tbl_B,tbl_B)
setkey(tbl_A,a)
setkey(tbl_B,x)

以及包含tbl_A中与tbl_B中至少一行匹配的行的预期结果:

   a b          c
1: c 3 -0.5403072
2: c 3 -0.5403072
3: d 4 -1.3353621
4: d 4 -1.3353621
5: e 5  1.1811730
6: e 5  1.1811730

2 个答案:

答案 0 :(得分:1)

再添加2个选项

tbl_A[fintersect(tbl_A[,.(a)], tbl_B[,.(a=x)])]

tbl_A[unique(tbl_A[tbl_B, nomatch=0L, which=TRUE])]

答案 1 :(得分:0)

我不确定它是多么富有表现力(如果没有道歉),但这似乎有效:

tbl_A[,.(a,b,c,any(a == tbl_B[,x])), by = a][V4==TRUE,.(a,b,c)]

我确信它可以改进 - 我昨天才发现任何()并且仍在测试它:)