【发布时间】:2011-10-25 04:32:02
【问题描述】:
data.table 对象现在有一个 := 运算符。是什么让这个运算符与所有其他赋值运算符不同?另外,它的用途是什么,它的速度有多快,什么时候应该避免?
【问题讨论】:
标签: r data.table colon-equals
data.table 对象现在有一个 := 运算符。是什么让这个运算符与所有其他赋值运算符不同?另外,它的用途是什么,它的速度有多快,什么时候应该避免?
【问题讨论】:
标签: r data.table colon-equals
这是一个示例,显示 10 分钟减少到 1 秒(来自homepage 上的新闻)。这就像对 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
和:
DT[,newcol:=sum(v),by=group] # like a fast transform() by group
我想不出任何理由来避免:=!除此之外,在for 循环内。由于:= 出现在DT[...] 内部,它带来了[.data.table 方法的小开销;例如,S3 调度并检查参数的存在和类型,例如i、by、nomatch 等。因此对于内部for 循环,有一个低开销的直接版本:=,称为@ 987654340@。有关更多详细信息和示例,请参阅?set。 set 的缺点包括 i 必须是行号(不能进行二分查找)并且不能与 by 结合使用。通过设置这些限制set 可以显着减少开销。
system.time(for (i in 1:1000) set(DT,i,"V1",i))
user system elapsed
0.016 0.000 0.018
【讨论】:
set(DT, i, "V1", i) 设置"V1" 列,而set(DT, i, colVar, i) 设置包含在colVar 变量中的列名称(例如,如果colVar = "V1" 之前完成)。引号表示按字面意思获取列名,而不是查找变量。