使用data.table,这是在一系列列中“扫出”统计数据的最快方法吗?
从(相当大的版本)DT
开始p <- 3
DT <- data.table(id=c("A","B","C"),x1=c(10,20,30),x2=c(20,30,10))
DT.totals <- DT[, list(id,total = x1+x2) ]
我想通过索引目标列(2:p)来跳过密钥来获得以下data.table结果:
id x1 x2
[1,] A 0.33 0.67
[2,] B 0.40 0.60
[3,] C 0.75 0.25
答案 0 :(得分:4)
我认为接近以下内容(使用相对较新的set()
函数)将是最快的:
DT <- data.table(id = c("A","B","C"), x1 = c(10,20,30), x2 = c(20,30,10))
total <- DT[ , x1 + x2]
rr <- seq_len(nrow(DT))
for(j in 2:3) set(DT, rr, j, DT[[j]]/total)
DT
# id x1 x2
# [1,] A 0.3333333 0.6666667
# [2,] B 0.4000000 0.6000000
# [3,] C 0.7500000 0.2500000
FWIW,对set()
的调用采用以下形式:
# set(x, i, j, value), where:
# x is a data.table
# i contains row indices
# j contains column indices
# value is the value to be assigned into the specified cells
与其他解决方案相比,我对此相对速度的怀疑是基于data.table's NEWS file中关于版本1.8.0中更改的部分的这一段:
o New function set(DT,i,j,value) allows fast assignment to elements of DT. Similar to := but avoids the overhead of [.data.table, so is much faster inside a loop. Less flexible than :=, but as flexible as matrix subassignment. Similar in spirit to setnames(), setcolorder(), setkey() and setattr(); i.e., assigns by reference with no copy at all. M = matrix(1,nrow=100000,ncol=100) DF = as.data.frame(M) DT = as.data.table(M) system.time(for (i in 1:1000) DF[i,1L] <- i) # 591.000s system.time(for (i in 1:1000) DT[i,V1:=i]) # 1.158s system.time(for (i in 1:1000) M[i,1L] <- i) # 0.016s system.time(for (i in 1:1000) set(DT,i,1L,i)) # 0.027s