user3390169 user3390169 - 2 months ago 15
R Question

Rolling sum product by column

I have two matrices that I would like to multiply together such that each value of the resulting matrix would be a rolling sum-product of the same columns in the first two matrices.

x<-matrix(seq(1:30), ncol=3)
x
[,1] [,2] [,3]
[1,] 1 11 21
[2,] 2 12 22
[3,] 3 13 23
[4,] 4 14 24
[5,] 5 15 25
[6,] 6 16 26
[7,] 7 17 27
[8,] 8 18 28
[9,] 9 19 29
[10,] 10 20 30
y<-matrix(rep(seq(1:3), 4), ncol=3)/10
y
[,1] [,2] [,3]
[1,] 0.1 0.2 0.3
[2,] 0.2 0.3 0.1
[3,] 0.3 0.1 0.2
[4,] 0.1 0.2 0.3


so the result would look like:

1.8 9.9 20.3
2.5 10.7 21.2
3.2 11.5 22.1
3.9 12.3 23
4.6 13.1 23.9
5.3 13.9 24.8
6 14.7 25.7


In example output above the value of
10.7
is calculated as:

output[2, 2] = 12 * 0.2 + 13 * 0.3 + 14 * 0.1 + 15 * 0.2


Does anybody know how to do that? I have been playing with the
RcppRoll
package but can't get the right answer. The faster the solution the better since this is part of an optimization that will take many iterations.

Answer

Using colSums:

t(
  sapply(1:(nrow(x) - nrow(y) + 1), function(i){
    colSums(x[i:((nrow(y)) + i - 1), ] * y)
    })
  )

Based on bigger example data (provided in ZheyuanLi's answer), microbenchmark:

Unit: milliseconds
 expr      min       lq     mean   median       uq      max neval cld
   zx 179.8928 186.8033 202.5204 192.3973 199.7500 299.5910   100  a 
   ZL 365.9814 368.3878 391.8303 370.0935 373.4502 489.5045   100   b