data.table使用常量更新连接

时间:2017-08-13 17:54:18

标签: r performance join data.table

我想基于连接和固定值更新data.table中的行子集。

d1 <- data.table(A = 5:1, B = letters[5:1])    
d2 <- data.table(C = letters[5:1], Z = 6:10)
current.val <- 5

我想要做的是根据与d2的连接更新d1,但仅限于d1中A == 5的位置。像这样的东西:

d1[d2, D := i.Z ,on=.(B==C, A==current.val)]

我当前的方法是向d2添加一个新列并将其设置为固定值并在连接中使用它:

d2[, current.val := 5]
d1[d2, D := i.Z ,on=.(B==C, A==current.val)]

这很有效,但似乎有很多开销。是否有更简单的方法在连接中使用常量值?

(8/14)基准测试的新比例示例:

d1 <- data.table(A = 100:1, B = 100000000:1, D = as.numeric(NA),  key = c("A", "B"))
d2 <- data.table(C = 100000000:1, Z = c(10:1) / 10, key = "C")
current.val <- 5

system.time(d1[cbind(d2, A = current.val), on = .(B = C, A), D := i.Z])
system.time({setkey(d1, B, A); d1[d1[d2][A == current.val], D := Z]; setkey(d1, A, B)})
system.time(d1[d1[d2][A == current.val], D := Z]) # fastest, if inverse key order is acceptable

2 个答案:

答案 0 :(得分:1)

  

我当前的方法是向d2添加一个新列并将其设置为固定值并在连接中使用它[...]是否有更简单的方法在连接中使用常量值?

这是一个很好的方式。或者,您可以使用cbind临时在联接内添加一列:

d1[cbind(d2, A = current.val), on=.(B = C, A), D := i.Z ]

实际上,c代替cbind在这里工作,但我觉得这是一种更奇怪的方法。

答案 1 :(得分:0)

只有五行,它不会有任何区别,但如果你想扩大规模,那么如果你在d1d2设置密钥,这项操作会快得多:< / p>

d1 <- data.table(A=5:1, B=letters[5:1], key="B")
d2 <- data.table(C=letters[5:1], Z=6:10, key="C")

然后,以下构造将给出所需的结果:

d1[d1[d2][A==current.val], D := Z]