什么时候应该在data.table中使用:=运算符?


88

data.table对象现在具有:=运算符。是什么使该运算符与所有其他赋值运算符不同?此外,它的用途是什么,速度快多少,何时应避免使用?

Answers:


94

这是一个示例,显示将10分钟缩短为1秒(来自首页上的NEWS )。这就像向a进行子分配,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 )

像这样放置:=inj允许更多成语:

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

和:

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

我想不出什么理由可以避免:=!除了,在for循环内。由于:=出现在内部DT[...],因此带有[.data.table方法的小开销;例如,S3调度和检查存在和类型的参数,例如ibynomatch等,所以里面的for循环,有一个低开销,直接版本的:=set。请参阅?set以获取更多详细信息和示例。setinclude的缺点是i必须是行号(不能进行二进制搜索),并且不能将其与结合使用by。通过做出这些限制set可以大大减少开销。

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

26
感谢您开发此软件包。我有种感觉,我将要修改很多代码以使用此软件包。
Iterator

1
在聊天中,我被要求自问/回答(显然是鼓励的)-这个问题在这里
Matt Dowle 2011年

4
@MatthewDowle想包含何时不使用:=并改为使用set()的解释吗?
阿里·弗里德曼

2
@MatthewDowle如果可以的话,我会再次+1。
阿里·弗里德曼

3
@jabberwocky没问题。set(DT, i, "V1", i)设置"V1"列,同时set(DT, i, colVar, i)设置包含在colVar变量中的列名(例如,如果之前colVar = "V1"已完成)。用引号引起来的是按字面上的名称而不是查找变量。
马特·道尔
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.