加速data.table中的行式操作

时间:2013-05-24 06:11:05

标签: r data.table

我对tapply的速度提升有多大的印象,我感到非常震惊 - 就像使用data.table与数据帧相比的操作一样。

例如:

df = data.frame(class = round(runif(1e6,1,1000)), x=rnorm(1e6))
DT = data.table(df)

# takes ages if somefun is complex
res1 = tapply(df$x, df$class, somefun) 

# takes much faster 
setkey(DT, class)
res2 = DT[,somefun(x),by=class] 

然而,我并没有完全让它比apply中的数据帧明显更快地工作 - 就像操作一样(即需要将函数应用于每一行的情况)。

df = data.frame(x1 = rnorm(1e6), x2=rnorm(1e6))
DT = data.table(df)

# takes ages if somefun is complex
res1 = apply(df, 1, somefun) 

# not much improvement, if at all 
DT[,rowid:=.I] # or: DT$rowid = 1:nrow(DT)
setkey(DT, rowid)
res2 = DT[,somefun1(x1,x2),by=rowid] 

这真的只是预期还是有一些技巧?

2 个答案:

答案 0 :(得分:5)

如果你无法对你的函数进行矢量化(因为递归...),那么你就属于Rcpp领域。 使用Rcppdata.table的常规规则是

  1. 相应地塑造data.table setkey ...)
  2. 写下C?C++函数说f,其中包含Rcpp::DataFrame并返回Rcpp::List
  3. 通过cppOutList <- f(DT)DT[,names(cppOutList):=cppOutList]
  4. 参考更新

    这样做通常可以让您节省数量级

答案 1 :(得分:0)

使用set可以大大提高行方式操作的速度。这里有一个很好的基准:Row operations in data.table using `by = .I`