# File: combmat.R # Purpose: add up matrices with different dimensions # Input: a list of 2-dimensional matrices # Output: a combined matrix # Author: Kay Cichini # Date: Nov. 23th 2011 combmat <- function(m_l = list(NA)){ n_m <- length(m_l) # no. of matrices used rownames_l <- lapply(m_l, rownames) # list of rownames colnames_l <- lapply(m_l, colnames) # list of colnames rownames_new <- unique(unlist(rownames_l)) # new, general rownames colnames_new <- unique(unlist(colnames_l)) # new, general colnames dimnames_new = list(rownames_new, colnames_new) m_new <- matrix(nrow = length(rownames_new), ncol = length(colnames_new), data = 0, dimnames = dimnames_new) m_interm_arr <- # array of intermediate array(m_new, dim = c(length(rownames_new), # matrices with same no. of length(colnames_new), n_m), # dimensions as elements in dimnames = dimnames_new) # list of input matrices # take i-th element in list of imput matrices and add # its values according to the appropiate row and col indexes # in i-th dimension (i-th matrix) within array: for (i in 1:n_m) { m_interm_arr[,,i][rownames_l[[i]], colnames_l[[i]]] <- m_l[[i]] } return(apply(m_interm_arr, c(1,2), sum)) } # Example: print(m1 <- matrix(sample(1:40), 4, 10, dimnames = list(1:4,1:10))) print(m2 <- matrix(sample(1:40), 10, 4, dimnames = list(1:10,1:4))) combmat(m_l = list(m1, m2))
It is very likely that someone else may come to a more effective approach - I'd be happy to here about improvements or if there is a package/function doing the same...
Hi Kay,
ReplyDeleteI like your solution, but how about the following (using your m1 and m2 matrices)?
library(reshape2)
m_comb <- do.call(rbind, lapply(list(m1, m2), melt))
acast(m_comb, m_comb$Var1~m_comb$Var2, sum)
However, if colname classes are mixed, this re-sorts columns alphabetically, with numbers stored as character... although mixedorder in gtools could be used to sort a bit more sensibly:
library(gtools)
m_sum[, mixedorder(colnames(m_sum))]
Cheers,
John
Hi John,
ReplyDeleteMany thanks for your input. Actually, I was searching for something like this! In the end, my post my serve as an example for yielding equal results with build-in functions and by hand..
Best regards,
Kay