Еще две возможности: sweep
и scale
(последняя работает только по столбцам, и мне кажется, это немного хак).
coef <- c(1.5,2.4,3.9,4.4)
y <- matrix(c(seq(1,17,by=4),
seq(2,18,by=4),
c(12,7,2,15,39,
45,8,12,45,7)),
ncol=4)
t(t(y)*coef)
t(apply(y,1,"*",coef))
sweep(y,2,coef,"*")
scale(y,center=FALSE,scale=1/coef)
library(rbenchmark)
benchmark(t(t(y)*coef),
y %*% diag(coef),
t(apply(y,1,"*",coef)),
sweep(y,2,coef,"*"),
scale(y,center=FALSE,scale=1/coef),
replications=1e4)
test replications elapsed relative
5 scale(y, center = FALSE, scale = 1/coef) 10000 0.990 4.342105
4 sweep(y, 2, coef, "*") 10000 0.846 3.710526
3 t(apply(y, 1, "*", coef)) 10000 1.537 6.741228
1 t(t(y) * coef) 10000 0.228 1.000000
2 y %*% diag(coef) 10000 0.365 1.600877
edit : добавлено y %*% diag(coef)
из @baptiste [не самое быстрое, хотя это может быть так для большой проблемы с достаточно оптимизированным пакетом BLAS ...] [и это было быстрее всего в другом испытании, так что, возможно, у меня не было стабильной оценки]
edit : исправлена опечатка в t(t(y)*coef)
[благодаря Тимуру Штатланду] (но не обновлял тайминги, поэтому они могли быть немного не в порядке ...)
Я также попытался library(Matrix); y %*% Diagonal(x=coef)
, что очень медленно для этого примера, но может быть быстрым для большой матрицы (??). (Я также пытался построить диагональную матрицу только один раз, но даже умножение на заранее определенную матрицу было медленным в этом примере (в 25 раз медленнее, чем в лучшем случае, в 47 раз медленнее при определении матрицы на лету.)
У меня есть мягкое предпочтение sweep
, так как я думаю, что оно наиболее четко выражает выполняемую операцию («умножьте столбцы на элементы coef
»)