Computação eficiente de uma combinação linear de colunas de dados.

eu tenhonc colunas em um data.table enc escalares em um vetor. Eu quero dar umacombinação linear das colunas, mas não sei de antemão quais colunas vou usar.Qual é a maneira mais eficiente de fazer isso?

configuração
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])
maneiras de fazer isso

Suponha que eu queira usar as primeiras quatro colunas. Eu posso escrever manualmente:

DT[,list(cf['A']*A+cf['B']*B+cf['C']*C+cf['D']*D)]

Eu posso pensar em duas formas automáticas (que funcionam sem saber que A-E deve ser usado):

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]
avaliação comparativa

Espero que oas.matrix para fazer a segunda opção lenta, e realmente não tem intuição para a velocidade deMap-Reduce combinações.

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

Eu chego em qualquer lugar de uma desaceleração de 5% a 40% por cento em relação à abordagem manual quando eu repito obenchmark ligar.

Minha aplicação

As dimensões aqui -n elength(mycols) - estão perto do que estou trabalhando, mas estarei executando esses cálculos muitas vezes, alterando o vetor coeficiente,cf.

questionAnswers(2)

yourAnswerToTheQuestion