How to calculate weighted means for each column (or row) of a matrix using the columns (or rows) from another matrix?

Viewed 211

I have two identically sized matrices: m and w that look as follows:

set.seed(5)
m <- matrix(rexp(90), nrow = 3 , ncol = 3)

set.seed(10)
w <- matrix(rexp(90), nrow = 3 , ncol = 3)

I would like to calculate the weighted means of m using w as weights. To be more precise, I would like to do this for each rows (or columns) of m using the same rows (or columns) of w as weights. The results would be ideally stored in a vector. For example:

w_mean_col <- c(weighted.mean(m[,1] , w[,1]) ,
            weighted.mean(m[,2] , w[,2]) ,
            weighted.mean(m[,3] , w[,3]) )

for the columns, and:

w_mean_row <- c(weighted.mean(m[1,] , w[1,]) ,
                weighted.mean(m[2,] , w[2,]) ,
                weighted.mean(m[3,] , w[3,]) ) 

The code is very impractical when working with very large matrices. Would there be better code to do this automatically?

2 Answers

You may simply do

colSums(m*w)/colSums(w)  ## columns
# [1] 0.2519816 0.4546775 0.7812545
rowSums(m*w)/rowSums(w)  ## rows
# [1] 0.2147437 0.5273465 1.0559481

which should be fastest.

Or, if you stick to weighted.mean(), you may use mapply.

mapply(weighted.mean, as.data.frame(m), as.data.frame(w), USE.NAMES=F)  ## columns
# [1] 0.2519816 0.4546775 0.7812545
mapply(weighted.mean, as.data.frame(t(m)), as.data.frame(t(w)), USE.NAMES=F)  ## rows
# [1] 0.2147437 0.5273465 1.0559481

We could use tidyverse

library(dplyr)
as.data.frame(m) %>%
   summarise(across(everything(), 
       ~ weighted.mean(., as.data.frame(w)[[cur_column()]])))

or we can use Map after splitting the matrix by column, and then apply the weighted.mean to get the corresponding means

unlist(Map(weighted.mean, asplit(m, 2), asplit(w, 2)))

If it is by row, then split by row

unlist(Map(weighted.mean, asplit(m, 1), asplit(w, 1)))

Or can use a for loop

w_mean_col <- numeric(ncol(m))
for(i in seq_along(w_mean_col)) w_mean_col[i] <- weighted.mean(m[,i], w[,i])
Related