nc
data.table に列があり、ベクトルにスカラーnc
があります。列の線形結合を取りたいのですが、使用する列が前もってわかりません。これを行う最も効率的な方法は何ですか?
設定
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])
それを行う方法
最初の 4 つの列を使用するとします。私は手動で書くことができます:
DT[,list(cf['A']*A+cf['B']*B+cf['C']*C+cf['D']*D)]
2 つの自動的な方法を考えることができます (すべて AE を使用する必要があることを知らなくても機能します)。
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]
ベンチマーク
私は 2 番目のオプションを遅くすることを期待しており、 -の組み合わせ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
通話を繰り返すと、手動のアプローチに比べて 5% から 40% の速度低下が見られbenchmark
ます。
私のアプリケーション
ここの次元 --n
とlength(mycols)
-- は、私が作業しているものに近いですが、係数ベクトルを変更して、これらの計算を何度も実行しcf
ます。