1

I want to do elementwise multiplication of a vector with every rows of a very big binary matrix. length of my vector is equal to number of columns of my matrix. I have implemented using for loop as follow, but it's very slow. Does anyone knows solution to speed it up?

A <- c()
M # Binary matric
W <- matrix(0, nrow=nrow(M), ncol=ncol(M))
W <- data.frame(W)
for (i in 1:nrow(W)) {
    W[i,] <- M[i,] * A
}
Ben Bolker
  • 192,494
  • 24
  • 350
  • 426
user51661
  • 15
  • 7
  • 2
    Turning `W` into a data.frame is a mistake. AFAIK, matrix subassignment is faster than data.frame subassignment. – Roland Sep 21 '15 at 09:12

3 Answers3

4

The accepted answer is certainly not the fastest way to do this on R. This is significantly faster, I don't know if it is the fastest way:

M * outer(rep.int(1L, nrow(M)), v)

Note also a C/C++ based solution to this problem for both matrices and data frames is provided by collapse::TRA (which in addition supports grouped sweeping operations). Benckmark:

library(microbenchmark)
library(collapse)

all_obj_equal(t(t(M) * v), M * outer(rep.int(1L, nrow(M)), v), TRA(M, v, "*"))
[1] TRUE

microbenchmark(t(t(M) * v), M * outer(rep.int(1L, nrow(M)), v), TRA(M, v, "*"), times = 100, unit = "relative")
Unit: relative
                                 expr       min        lq      mean    median        uq      max neval cld
                          t(t(M) * v) 16.256563 12.703469 10.771698 12.113859 10.148008 8.365288   100   c
   M * outer(rep.int(1L, nrow(M)), v)  1.097177  1.449713  1.375522  1.426085  1.273911 1.785404   100  b 
                       TRA(M, v, "*")  1.000000  1.000000  1.000000  1.000000  1.000000 1.000000   100 a 

(Note: M here is the Eora 26 ICIO Matrix 2015 of Dimension 4915 x 4915, v is 1/output)

Sebastian
  • 704
  • 5
  • 9
3

Use vector recycling, Since matrices are filled by columns, you need to transpose:

t(t(M) * v)
Roland
  • 122,144
  • 10
  • 182
  • 276
1

You can use Rfast::eachrow wich is quite fast.

M<-Rfast::matrnorm(1000,1000)
v=rnorm(1000)

Rfast2::benchmark(Rfast::eachrow(M,v,"*"),M * outer(rep.int(1L, nrow(M)), v),M * Rfast::Outer(rep.int(1, nrow(M)), v),times = 100)
   milliseconds 
                                            min      mean      max
Rfast::eachrow(M, v, "*")                2.4790  4.440305  12.3601
M * outer(rep.int(1L, nrow(M)), v)       5.7612 25.952871 807.1748
M * Rfast::Outer(rep.int(1, nrow(M)), v) 3.4185  7.525743 204.3348
Manos Papadakis
  • 513
  • 4
  • 14