【发布时间】:2020-12-16 09:10:53
【问题描述】:
我需要在两个 data.tables 之间迭代地执行连接,其中列名是我从函数输入的变量。我一直在使用 data.tables 'on' 功能执行连接,但由于变量列名似乎无法识别而遇到问题。
例如,假设我们有两个表,Table_1 和 Table_2,如下:
require(data.table)
n <- 20
Table_1 <- data.table(A = seq_len(n) + 1,
B = seq_len(n) + 3,
C = seq_len(n) + 5)
m <- 15
Table_2 <- data.table(D = seq_len(m) + 7,
E = seq_len(m) + 9,
F = seq_len(m) + 12)
我可以在明确定义列的地方轻松执行连接。例如
Table_2[Table_1,on = .(F = C),sum(D.na.rm = T)]
但是,我需要做的是在不同的列上执行多个匹配,例如:
require(purrr)
pmap(.l = CJ(x = c("D","F"),y = c("A","B")),
.f = function(x,y) Table_2[Table_1,on = .(x = y),sum(C,na.rm = T)])
我收到以下错误:
Error in colnamesInt(x, names(on), check_dups = FALSE) :
argument specifying columns specify non existing column(s): cols[1]='x'
我尝试了各种方法,例如:
- 用“eval()”或“noquote”将 x 和 y 括起来
- 将 pmap 函数放在 data.table 中,而不是如上所示的外部。
这两种方法都不起作用。 任何帮助都将不胜感激,因为必须编写单独的连接语句显然效率极低!
谢谢, 菲尔
编辑:
下面有人建议我应该考虑使用“合并”功能。 从理论上讲,这适用于上面的示例,但是我没有在上面提到我实际上需要使用非 equi 连接,这意味着,据我所知,我不能使用“合并”。在我的实际案例中,我需要通过函数将列名映射到等值和非等值连接的组合。
我提供了一个带有目标输出的后续示例。该示例只有两个连接语句,但我需要足够灵活的解决方案来处理多个:
我想要下面的表达式:
pmap(.l = list(x1 = "D",x2 = "A",x3 = "E",x4 = "B"),
.f = function(x1,x2,x3,x4) (Table_2[Table_1,on = .(x1 = x2,
x3 > x4),sum(C,na.rm = T)]))
要给出与此相同的输出:
Table_2[Table_1,on = .(D = A,
E > B),sum(C,na.rm = T)]
即本例中为 310。
再次感谢, 菲尔
【问题讨论】:
-
你能根据输入显示预期的输出吗?
-
你试过 merge 功能吗? by.x 和 by.y 参数要求字符串作为列名,也可以在变量中。
-
@sindri_baldur - 请参阅上面我修改后的问题以及目标输出。谢谢
-
@cdalitz - 谢谢。它可以在上面的示例中使用,但我没有提到需要非 equi 连接的真实场景的全部复杂性。请参阅我修改后的问题和目标输出。
标签: r join data.table