我有一个大约有2500万行的数据集。我正在获取这些行的子集并执行一个工作正常的函数。但是,我需要做的是使用新值更新原始数据集中的值,同时保留其余值。我确信这很简单,但我无法理解它。
这是我正在处理的简化版本:
require("data.table")
df <-data.frame(AREA_CD = c(sample(1:25000000, 25000000, replace=FALSE)), ALLOCATED = 0, ASSIGNED = "A", ID_CD = c(1:25000000))
df$ID_CD <- interaction( "ID", df$ID_CD, sep = "")
dt <- as.data.table(df)
sub_dt <- dt[5:2004,]
sub_dt[,ALLOCATED:=ALLOCATED+1]
sub_dt[,ASSIGNED:="B"]
我所追求的是来自sub_dt
的'ALLOCATED'和'ASSIGNED'中的值,以根据'ID_CD'列替换dt
中的'ALLOCATED'和'ASSIGNED'值。根据我的例子,我想要的输出仍然有2500万行,但有2,000行更新。任何帮助将非常感激。感谢。
答案 0 :(得分:2)
David Arenburg提供的答案in his comment解释了如何将修改后的数据子集重新加入原始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
&#34;到位&#34;比创建子集和以后加入要快得多。需要复制操作才能使用未修改版本的dt
启动每个基准测试运行。因此,复制操作也是基准测试。
data.table
版本1.10.4。