Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Weighted mean across several matrices - element by element

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!

like image 471
user2323534 Avatar asked Oct 18 '25 23:10

user2323534


1 Answers

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
like image 78
akrun Avatar answered Oct 20 '25 14:10

akrun



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!