Automatic Multiplication Between Vector and Matrix

I have this R code:

> coef [1] 1.5 2.4 3.9 4.4 > y [,1] [,2] [,3] [,4] [1,] 1 2 12 45 [2,] 5 6 7 8 [3,] 9 10 2 12 [4,] 13 14 15 45 [5,] 17 18 39 7 

I need to multiply each column value by the corresponding coefficient. The result should be:

 First column: 1*1.5 5*1.5 9*1.5 13*1.5 17*1.5 Second column: 2*2.4 6*2.4 10*2.4 14*2.4 18*2.4 Third column: 12*3.9 7*3.9 2*3.9 15*3.9 39*3.9 Fourth column: 45*4.4 8*4.4 12*4.4 45*4.4 7*4.4 

All column values ​​corrected by the same coefficient at the same index in the vector.

How can I do this calculation?

The solution may be:

 > y[,1] <- y[,1] * coef[1] > y[,2] <- y[,2] * coef[2] > y[,3] <- y[,3] * coef[3] > y[,4] <- y[,4] * coef[4] 

But it does not seem too optimized! Is something better?

Thanks!

+4
source share
4 answers

This will give you what you want:

 t( t(y) * coef ) 
+7
source

Two more possibilities: sweep and scale (the latter works only on columns and seems a bit hacked to me).

 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 : added y %*% diag(coef) from @baptiste [not faster, although it could be for a big problem with a fairly optimized BLAS package ...] [and it was faster in another test, so I might just not have stable evaluation]

edit : typo fixed in t(t(y)*coef) [thanks Timur Shtatland] (but failed to update the timings, so they can be turned off a bit ...)

I also tried library(Matrix); y %*% Diagonal(x=coef) library(Matrix); y %*% Diagonal(x=coef) , which is very slow for this example, but can be fast for a large matrix (??). (I also tried to build the diagonal matrix only once, but even in this example, even multiplying by a predefined matrix was slow (25 times slower than the best, versus 47 times slower when defining the matrix on the fly.)

I have a soft sweep preference as I think it most clearly expresses the operation being performed ("multiply columns by coef elements")

+6
source
  apply(y, 1, "*", coef) # -- result -- [,1] [,2] [,3] [,4] [,5] [1,] 1.5 7.5 13.5 19.5 25.5 [2,] 4.8 14.4 24.0 33.6 43.2 [3,] 46.8 27.3 7.8 58.5 152.1 [4,] 198.0 35.2 52.8 198.0 30.8 
+5
source

Late entry:

 coef[col(y)]*y 

On my system, this is the fastest.

  test replications elapsed relative 6 coef[col(y)] * y 10000 0.068 1.000 5 scale(y, center = FALSE, scale = 1/coef) 10000 0.640 9.412 4 sweep(y, 2, coef, "*") 10000 0.535 7.868 3 t(apply(y, 1, "*", coef)) 10000 0.837 12.309 1 t(t(y) * coef) 10000 0.176 2.588 2 y %*% diag(coef) 10000 0.187 2.750 
+3
source

All Articles