我想基于连接和固定值更新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
答案 0 :(得分:1)
我当前的方法是向d2添加一个新列并将其设置为固定值并在连接中使用它[...]是否有更简单的方法在连接中使用常量值?
这是一个很好的方式。或者,您可以使用cbind
临时在联接内添加一列:
d1[cbind(d2, A = current.val), on=.(B = C, A), D := i.Z ]
实际上,c
代替cbind
在这里工作,但我觉得这是一种更奇怪的方法。
答案 1 :(得分:0)
只有五行,它不会有任何区别,但如果你想扩大规模,那么如果你在d1
和d2
设置密钥,这项操作会快得多:< / 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]