data.table
对象现在拥有一个:=运算符。这个运算符与所有其他赋值运算符不同的是什么?还有,它有什么用途,速度比其他赋值运算符快多少,以及在什么情况下应该避免使用它?
data.table
对象现在拥有一个:=运算符。这个运算符与所有其他赋值运算符不同的是什么?还有,它有什么用途,速度比其他赋值运算符快多少,以及在什么情况下应该避免使用它?
这里有一个例子,展示了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 )
将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
我想不出有什么理由避免使用:=
!除了在for
循环内部。由于:=
出现在DT[...]
中,它带来了[.data.table
方法的小开销;例如S3分配和检查参数的存在和类型,例如i
、by
、nomatch
等。因此,在for
循环内部,有一个低开销、直接版本的:=
,称为set
。请参见?set
以获取更多详细信息和示例。 set
的缺点包括必须是行号(没有二进制搜索)和不能与by
结合使用。通过这些限制,set
可以大大减少开销。
system.time(for (i in 1:1000) set(DT,i,"V1",i))
user system elapsed
0.016 0.000 0.018
set()
的第三个参数只是一个列名(如?set
中所定义)。您可能希望这是字面值(例如"V1"
)或保存在变量中(例如colName
,它可以包含"V1"
、"colA"
或其他列名)。DT[,]
内部的第二个参数始终是在数据表范围内计算的表达式。DT[,V1]
是最简单的情况,但像DT[,V1*V2]
和DT[,sum(V1)]
这样的东西更常见。这有帮助吗? - Matt Dowleset(DT, i, "V1", i)
会设置"V1"
列,而set(DT, i, colVar, i)
会设置colVar
变量中包含的列名(例如,如果之前执行了colVar = "V1"
)。引号表示字面上采用列名,而不是查找变量。 - Matt Dowle