与数据帧相比,我对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]
Run Code Online (Sandbox Code Playgroud)
但是,我并没有完全让它的工作速度明显快于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]
Run Code Online (Sandbox Code Playgroud)
这真的只是预期还是有一些技巧?
如果你无法对你的函数进行矢量化(因为递归...)那么你就属于Rcpp领土.通常的规则使用Rcpp和data.table是
data.table相应(setkey...)C?C++功能说f会带一个Rcpp::DataFrame并返回一个Rcpp::ListcppOutList <- f(DT),DT[,names(cppOutList):=cppOutList]这样做通常可以让您节省数量级