4

I have 'mylist" - a list of same size matrices:

mylist <- vector("list", 5) 
set.seed(123)
for(i in 1:5){
  mylist[[i]] <- matrix(rnorm(9), nrow = 3)
}

I also have a vector of weights 'mywgts' - same length as 'mylist'

mywgts <- c(0.8, 0.9, 1, 1.1, 1.2)

I need to calculate a weighted mean of these matrices - element by element. The result will be a 3 by 3 matrix where the first element is:

mylist[[1]][1,1]*mywgts[1] + mylist[[2]][1,1]*mywgts[2] + 
mylist[[3]][1,1]*mywgts[3] + mylist[[4]][1,1]*mywgts[4] + 
mylist[[5]][1,1]*mywgts[5]

I know how to do it by looping through all elements of a matrix. But I am looking for a more parsimonious/elegant R-like solution. Also - the actual length of 'mylist' is not known in advance.

Thank you for any hint!

user2323534
  • 585
  • 1
  • 6
  • 18

1 Answers1

5

You may try

 res <- Reduce(`+`,Map(`*`, mylist, mywgts))
 res
 #         [,1]       [,2]      [,3]
 #[1,]  0.6852912  0.2116715 0.7993867
 #[2,] -0.8815045 -1.9811868 1.2558095
 #[3,]  1.5150166  0.8780412 0.7254080

Map is a wrapper for mapply, which is a multivariate version of sapply. The function (*) is applied to the corresponding elements of first ('mylist') and second elements ('mywgts'), and then use Reduce to sum the corresponding elements of the list.

If you need the mean, divide by the length of 'mylist`.

  res/length(mylist)

Using the OP's calculation

mylist[[1]][1,1]*mywgts[1] + mylist[[2]][1,1]*mywgts[2] + 
mylist[[3]][1,1]*mywgts[3] + mylist[[4]][1,1]*mywgts[4] + 
mylist[[5]][1,1]*mywgts[5]
#[1] 0.6852912

mylist[[1]][1,2]*mywgts[1] + mylist[[2]][1,2]*mywgts[2] + 
mylist[[3]][1,2]*mywgts[3] + mylist[[4]][1,2]*mywgts[4] + 
mylist[[5]][1,2]*mywgts[5]
#[1] 0.2116715
akrun
  • 874,273
  • 37
  • 540
  • 662