【发布时间】:2017-08-13 17:54:17
【问题描述】:
我想根据联接和固定值更新 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
【问题讨论】:
-
您的解决方案看起来很简单。如果您不想创建列,请使用行索引,即
i1 <- d1[, .I[A==current.val]]; d1[i1, D:= d1[i1][d2, i.Z[i1], on = .(B==C)]] -
不确定您是否在那里进行了正确的基准测试。对于第二个,我收到“vecseq 中的错误 [...] Join results in more than 2^31 rows”。
-
弗兰克,请参阅下面@gcbenison 的回答 cmets。我会更新帖子以反映工作基准
标签: r performance join data.table