给定两个数据表(tbl_A和tbl_B),我想选择 中tbl_A具有匹配行的所有行tbl_B,并且我希望代码具有表现力。如果%in%为 data.tables 定义了该运算符,那么像这样的操作将是理想的:
subset <- tbl_A[tbl_A %in% tbl_B]
Run Code Online (Sandbox Code Playgroud)
我可以想到很多方法来实现我想要的,例如:
# 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][]
Run Code Online (Sandbox Code Playgroud)
但每个表达式都很难阅读,而且乍一看代码在做什么并不明显。有没有更惯用/更具表现力的方式来完成这项任务?
为了举例,这里有一些玩具 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)
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
我不确定它的表现力如何(如果没有的话抱歉)但这似乎有效:
tbl_A[,.(a,b,c,any(a == tbl_B[,x])), by = a][V4==TRUE,.(a,b,c)]
Run Code Online (Sandbox Code Playgroud)
我确信它可以改进 - 我昨天才发现 any() 并且仍在测试它:)