Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R data.table使用.SD时聚合速度慢_R_Data.table - Fatal编程技术网

R data.table使用.SD时聚合速度慢

R data.table使用.SD时聚合速度慢,r,data.table,R,Data.table,我正在对data.table(优秀的软件包!!!)进行聚合,我发现.SD变量在很多方面都非常有用。但是,当有许多组时,使用它会显著降低计算速度。下面是一个例子: # A moderately big data.table x = data.table(id=sample(1e4,1e5,replace=T), code=factor(sample(2,1e5,replace=T)), z=runif(1e5)

我正在对data.table(优秀的软件包!!!)进行聚合,我发现.SD变量在很多方面都非常有用。但是,当有许多组时,使用它会显著降低计算速度。下面是一个例子:

# A moderately big data.table
x = data.table(id=sample(1e4,1e5,replace=T),
               code=factor(sample(2,1e5,replace=T)),
               z=runif(1e5)
              )

setkey(x,id,code)

system.time(x[,list(code2=nrow(.SD[code==2]), total=.N), by=id])
##  user  system elapsed 
##  6.226   0.000   6.242

system.time(x[,list(code2=sum(code==2), total=.N), by=id])
## user  system elapsed 
## 0.497   0.000   0.498

system.time(x[,list(code2=.SD[code==2,.N], total=.N), by=id])
## user  system elapsed 
## 6.152   0.000   6.168

我做错什么了吗?我应该避免使用.SD来支持单个列吗?提前感谢。

尝试通过将计算分为两个步骤,然后合并生成的数据帧来解决此问题:

system.time({
  x2 <- x[code==2, list(code2=.N), by=id]
  xt <- x[, list(total=.N), by=id]
  print(x2[xt])
})
我是否做错了什么事,即我是否应该避免
.SD
,而支持单个列

是的,没错。如果您确实正在使用
.SD
中的所有数据,请仅使用
.SD
。您还可能会发现对
nrow()
的调用和对
[.data.table
的子查询调用也是罪魁祸首:使用
Rprof
进行确认

见以下最后几句:

常见问题解答2.1如何避免编写很长的j表达式?您说过我应该使用列名,但我有很多列。
分组时,
j
表达式可以使用列名作为变量,如下所示: 您知道,但它也可以使用一个保留符号
.SD
,它表示 每个组(不包括分组)的Data.table的子集 列),所以总结一下你所有的列
DT[,lappy(.SD,sum),by=grp]
。这可能看起来很棘手,但很快就能解决 编写并快速运行。注意,您不必创建匿名 功能。有关与其他功能的比较,请参见计时小插曲和wiki 方法:
.SD
对象在内部高效地实现,并且 比将参数传递给函数更有效。请不要这样做 虽然:
DT[,sum(.SD[,“sales”,with=FALSE]),by=grp]
。这很有效,但非常有用 低效和不雅观。这是我们的初衷:
DT[,sum(sales),by=grp]
可能快100倍。

另请参见常见问题3.1的第一个项目符号:

常见问题解答3.1我有20列和大量行。为什么一列的表达式如此快速?
有几个原因:
--只有那一列是正确的 分组后,其他19个被忽略,因为
数据。表检查
j
表达式,并意识到它不使用其他列

data.table
检查
j
并看到
.SD
符号时,效率增益就消失了。它必须为每个组填充整个
.SD
子集,即使您不使用其所有列。
data.table
很难知道您选择了
.SD
的哪些列实际上正在使用(
j
可以包含
if
s,例如)。但是,如果您仍然需要它们,当然这并不重要,例如在
DT[,lapply(.SD,sum),by=…]
中。这是
.SD
的理想用法

因此,是的,尽可能避免使用
.SD
。直接使用列名来提供数据。表对
j
的优化是最好的机会。在
j
中仅存在符号
.SD
是很重要的


这就是引入
.SDcols
的原因。因此,如果只需要子集,您可以告诉
数据.table
哪些列应该在
.SD
中。否则,
数据.table
将使用所有列填充
.SD
,以防
j
需要它们。

(+1)我会用
x2
替换
x2
,实际上这比
x[,list(sum(code==2),.N),by=id]
(有问题的示例2)快得多,不是吗!可能是因为你避免了对每个组重复调用
=
(这些小向量的相关分配等)。@Arun你确定吗?
x2[xt][is.na(code2
有一些行。你只是得到了
NA
而不是
0
。可能是错误的,只是看得很快。@MatthewDowle,不是,我只是说在
x2
的步骤中,x2
有9921行而不是9999行。当然,在最后,用x[y],这些行得到了NA。我想用
J(关键列)进行索引
应该比
逻辑索引快
…我弄错了吗?@Arun对单个列的单个向量扫描是一种特殊情况:
unique(id)
调用无论如何也必须扫描每个项,然后再加上加入的时间。请检查一下,
x2
有9999行,而不是9921行,这不是一个问题?(这就是你上面的评论所暗示的)。非常感谢!我被短语“该.SD对象在内部有效地实现,并且比将参数传递给函数更有效”所欺骗,并且不理解“尽管如此,请不要这样做:DT[,sum(.SD[,“sales”,with=FALSE]),by=grp]”由于with=FALSE。这将大大加快我的代码的速度!@vsalmendra啊,是的,它可能会更清晰。这是过去留给社区讨论的事情。最终我们希望改进
j
优化,这样用户就不需要知道这样的事情了。@vsalmendra我现在为下一版本改进了FAQ 2.1。
         id code2 total
   1:     1     6    14
   2:     2     8    10
   3:     3     7    13
   4:     4     5    13
   5:     5     9    18
  ---                  
9995:  9996     4     9
9996:  9997     3     6
9997:  9998     6    10
9998:  9999     3     4
9999: 10000     3     6
   user  system elapsed 
   0.05    0.00    0.04