【发布时间】:2013-10-17 05:28:10
【问题描述】:
我在 data.table 中有 nc 列,在向量中有 nc 标量。我想获取linear combination 的列,但我不知道我将使用哪些列。 最有效的方法是什么?
设置
require(data.table)
set.seed(1)
n <- 1e5
nc <- 5
cf <- setNames(rnorm(nc),LETTERS[1:nc])
DT <- setnames(data.table(replicate(nc,rnorm(n))),LETTERS[1:nc])
方法
假设我想使用前四列。我可以手动写:
DT[,list(cf['A']*A+cf['B']*B+cf['C']*C+cf['D']*D)]
我可以想到两种自动方式(在不知道应该全部使用 A-E 的情况下工作):
mycols <- LETTERS[1:4] # the first four columns
DT[,list(as.matrix(.SD)%*%cf[mycols]),.SDcols=mycols]
DT[,list(Reduce(`+`,Map(`*`,cf[mycols],.SD))),.SDcols=mycols]
基准测试
我预计as.matrix 会使第二个选项变慢,并且对Map-Reduce 组合的速度真的没有直觉。
require(rbenchmark)
options(datatable.verbose=FALSE) # in case you have it turned on
benchmark(
manual=DT[,list(cf['A']*A+cf['B']*B+cf['C']*C+cf['D']*D)],
coerce=DT[,list(as.matrix(.SD)%*%cf[mycols]),.SDcols=mycols],
maprdc=DT[,list(Reduce(`+`,Map(`*`,cf[mycols],.SD))),.SDcols=mycols]
)[,1:6]
test replications elapsed relative user.self sys.self
2 coerce 100 2.47 1.342 1.95 0.51
1 manual 100 1.84 1.000 1.53 0.31
3 maprdc 100 2.40 1.304 1.62 0.75
当我重复benchmark 调用时,相对于手动方法,我的速度会降低 5% 到 40%。
我的申请
这里的尺寸——n 和 length(mycols)——与我正在使用的尺寸接近,但我将多次运行这些计算,改变系数向量 cf。
【问题讨论】:
标签: r performance linear-algebra data.table