R data.table中的性能注意事项get()

R data.table中的性能注意事项get(),r,loops,data.table,R,Loops,Data.table,我一直在循环中使用get()来操作I引用多个其他列的j列 我想知道是否有更快/更有效的方法?有性能方面的考虑吗 下面是我想到的操作类型的一个最小示例: require(data.table) # version 1.12.8 dt = data.table(v1=c(1,2,NA),v2=c(0,0,1),v3=c(0,0,0)) for (i in 1:2){ dt[ is.na(get(paste0('v',i))), (paste0('v',i)):= get(paste0('v

我一直在循环中使用get()来操作I引用多个其他列的j列

我想知道是否有更快/更有效的方法?有性能方面的考虑吗

下面是我想到的操作类型的一个最小示例:

require(data.table) # version 1.12.8
dt = data.table(v1=c(1,2,NA),v2=c(0,0,1),v3=c(0,0,0))
for (i in 1:2){
     dt[ is.na(get(paste0('v',i))), (paste0('v',i)):= get(paste0('v',i+1))+2 ][]
}
我使用的实际表要大得多(约500万行,约300列)


如果您有任何想法,我将不胜感激。

我们可以使用
set
,它将分配到适当的位置

library(data.table)
for(j in 1:2) {
    i1 <- which(is.na(dt[[j]]))
    set(dt, i = i1, j = j, value = dt[[j+1]][i1]+ 2)
 }

dt
#   v1 v2 v3
#1:  1  0  0
#2:  2  0  0
#3:  3  1  0

是的,您的
for
循环会大大降低您的速度。即使是一个简单的
lappy
(可能还有更优雅的方法),也会为您带来显著的性能提升:

库(data.table)

dt这似乎有效,谢谢。诚然,我不知道set()将向量作为参数i。尝试对较大的数据使用apply函数,它将比loopsthanks linog使用更少的内存空间。似乎也比上面提出的“set()”方法快。dt对象似乎在执行lappy(..)片段时被直接更改,因此我甚至不需要像这样提取输出。(我只想继续直接处理dt中的操纵列)。很好!是的,你说得对,我没有想过回头看
dt
:=
通过引用原始
数据进行更改。表确实是。我将@akrun提出的
set
解决方案添加到基准测试中,因为它也会引起其他人的兴趣。如果答案适合你,你能接受吗?对不起,我想我必须站在@akrun一边。我还向基准测试添加了set(),得到了与您相同的结果。。但是:然后我在我的真实数据集上测试了它,set()在“大数据”上似乎快得多。直觉上,这似乎是有道理的,因为你的“lappy”方法似乎产生了很多开销(想想每个元素的dt的所有副本都经过了lappy)。如果数据非常大,这似乎是加起来的。遗憾的是,get()语法(类似于loop或lappy)对我来说更具可读性/直观性。。。无论如何,非常感谢!!好的,没问题,很高兴知道。正如我刚才所说,有比拉普拉(Lappy)更优雅的解决方案
setDF(dt)
i1 <- is.na(dt[-length(dt)])
dt[-length(dt)][i1] <- dt[-1][i1] + 2
dt
#  v1 v2 v3
#1  1  0  0
#2  2  0  0
#3  3  1  0