大卫·阿伦堡提供的答案在他的评论中解释如何将修改后的数据子集连接回原始数据data.table
.
但是,我想知道为什么OP不直接在原始版本中应用更改data.table
引用使用返回列表的函数:
my_fun <- function(alloc, assig) {
list(
alloc + 1,
"B")
}
使用此函数可以直接在data.table
:
dt[5:2004, c("ALLOCATED", "ASSIGNED") := my_fun(ALLOCATED, ASSIGNED)]
dt[1:7]
# AREA_CD ALLOCATED ASSIGNED ID_CD
#1: 1944 0 A ID1
#2: 3265 0 A ID2
#3: 15415 0 A ID3
#4: 14121 0 A ID4
#5: 10546 1 B ID5
#6: 2263 1 B ID6
#7: 12339 1 B ID7
基准
由于内存限制,仅使用具有 250 万行(而不是 OP 中的 2500 万行)的较小数据集。
library(microbenchmark)
setDT(df) # coerce df to data.table
microbenchmark(
copy = dt <- copy(df),
join = {
dt <- copy(df)
sub_dt <- dt[5:2004,]
sub_dt[,ALLOCATED:=ALLOCATED+1]
sub_dt[,ASSIGNED:="B"]
dt[sub_dt, `:=`(ALLOCATED = i.ALLOCATED, ASSIGNED = i.ASSIGNED), on = .(ID_CD)]
},
byref = {
dt <- copy(df)
dt[5:2004, c("ALLOCATED", "ASSIGNED") := my_fun(ALLOCATED, ASSIGNED)]
},
times = 10L
)
#Unit: milliseconds
# expr min lq mean median uq max neval
# copy 13.80400 14.07850 28.22882 14.15836 14.39643 154.70570 10
# join 239.36476 240.72745 244.27668 243.52967 246.17104 255.06271 10
# byref 14.28806 14.47308 15.00056 14.63147 14.73134 18.71181 10
更新中data.table
“就地”比创建子集然后再加入要快得多。需要复制操作才能使用未修改的版本启动每个基准测试运行dt
。因此,复制操作也被基准化。
data.table
使用版本1.10.4。