什么时候在data.table中使用:=操作符?

时间:2021-10-18 07:08:40

data.table objects now have a := operator. What makes this operator different from all other assignment operators? Also, what are its uses, how much faster is it, and when should it be avoided?

数据。表对象现在有一个:=操作符。为什么这个运算符与其他所有赋值运算符不同?还有,它的用途是什么,它的速度有多快,什么时候应该避免?

1 个解决方案

#1


87  

Here is an example showing 10 minutes reduced to 1 second (from NEWS on homepage). It's like subassigning to a data.frame but doesn't copy the entire table each time.

这里有一个例子,10分钟缩短为1秒(从首页新闻开始)。这就像对data.frame进行子签名,但不会每次都复制整个表。

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,1] <- i)
     user  system elapsed 
  287.062 302.627 591.984 

system.time(for (i in 1:1000) DT[i,V1:=i])
     user  system elapsed 
    1.148   0.000   1.158     ( 511 times faster )

Putting the := in j like that allows more idioms :

将:=放在j中,这样就允许使用更多的习语:

DT["a",done:=TRUE]   # binary search for group 'a' and set a flag
DT[,newcol:=42]      # add a new column by reference (no copy of existing data)
DT[,col:=NULL]       # remove a column by reference

and :

和:

DT[,newcol:=sum(v),by=group]  # like a fast transform() by group

I can't think of any reasons to avoid := ! Other than, inside a for loop. Since := appears inside DT[...], it comes with the small overhead of the [.data.table method; e.g., S3 dispatch and checking for the presence and type of arguments such as i, by, nomatch etc. So for inside for loops, there is a low overhead, direct version of := called set. See ?set for more details and examples. The disadvantages of set include that i must be row numbers (no binary search) and you can't combine it with by. By making those restrictions set can reduce the overhead dramatically.

我想不出任何避免的理由:= !除了,在for循环中。因为:=出现在DT内[…,它附带[.data的小开销。表法;例如,S3调度和检查是否存在和类型的参数,如i、by、nomatch等。因此对于inside for循环,有一个低开销的、直接版本的:= call set。set的缺点是,i必须是行号(没有二进制搜索),并且不能与by合并。通过设置这些限制,可以显著减少开销。

system.time(for (i in 1:1000) set(DT,i,"V1",i))
     user  system elapsed 
    0.016   0.000   0.018

#1


87  

Here is an example showing 10 minutes reduced to 1 second (from NEWS on homepage). It's like subassigning to a data.frame but doesn't copy the entire table each time.

这里有一个例子,10分钟缩短为1秒(从首页新闻开始)。这就像对data.frame进行子签名,但不会每次都复制整个表。

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,1] <- i)
     user  system elapsed 
  287.062 302.627 591.984 

system.time(for (i in 1:1000) DT[i,V1:=i])
     user  system elapsed 
    1.148   0.000   1.158     ( 511 times faster )

Putting the := in j like that allows more idioms :

将:=放在j中,这样就允许使用更多的习语:

DT["a",done:=TRUE]   # binary search for group 'a' and set a flag
DT[,newcol:=42]      # add a new column by reference (no copy of existing data)
DT[,col:=NULL]       # remove a column by reference

and :

和:

DT[,newcol:=sum(v),by=group]  # like a fast transform() by group

I can't think of any reasons to avoid := ! Other than, inside a for loop. Since := appears inside DT[...], it comes with the small overhead of the [.data.table method; e.g., S3 dispatch and checking for the presence and type of arguments such as i, by, nomatch etc. So for inside for loops, there is a low overhead, direct version of := called set. See ?set for more details and examples. The disadvantages of set include that i must be row numbers (no binary search) and you can't combine it with by. By making those restrictions set can reduce the overhead dramatically.

我想不出任何避免的理由:= !除了,在for循环中。因为:=出现在DT内[…,它附带[.data的小开销。表法;例如,S3调度和检查是否存在和类型的参数,如i、by、nomatch等。因此对于inside for循环,有一个低开销的、直接版本的:= call set。set的缺点是,i必须是行号(没有二进制搜索),并且不能与by合并。通过设置这些限制,可以显著减少开销。

system.time(for (i in 1:1000) set(DT,i,"V1",i))
     user  system elapsed 
    0.016   0.000   0.018