R: add matrices based on row and column names

扶醉桌前 提交于 2019-12-19 10:09:14

问题


I have two matrices I want to sum based on their row and column names. The matrices will not necessarily have all rows and columns in common - some may be missing from either matrix.

For example, consider two matrices A and B:

A=                 B=
  a b c d            a c d e
v 1 1 1 0          v 0 0 0 1
w 1 1 0 1          w 0 0 1 0
x 1 0 1 1          y 0 1 0 0
y 0 1 1 1          z 1 0 0 0

Column e is missing from matrix A and column b is missing from matrix B. Row z is missing from matrix A and row x is missing from matrix B.

The summed table I'm looking for is:

Sum=
  a b  c d e
v 1 1  1 0 1
w 1 1  0 2 0
x 1 0  1 1 na
y 0 1  2 1 0
z 1 na 0 0 0

The row and column ordering in the final matrix don't matter, as long as the matrix is complete, i.e. has all the data. Missing values don't have to be "Na", but could be "0" instead.

I'm not sure if there is a way to do this that doesn't involve for loops. Any help would be much appreciated.

My solution

I managed to do this easily by converting the matrices to dataframes, binding the dataframes by row and then casting the resulting dataframe back into a matrix. This looks like it works, but maybe someone could double check or let me know if there is a better way.

library(reshape2)
A_df=as.data.frame(as.table(A))
B_df=as.data.frame(as.table(B))

merged_df=rbind(A_df,B_df)

Summed_matrix=acast(merged_df, Var1 ~ Var2, sum)

merged_df looks like this:

   Var1 Var2 Freq
1     v    a    1
2     w    a    1
3     x    a    1
4     y    a    0
5     v    b    1
6     w    b    1
etc...

回答1:


May be you can try:

cAB <- union(colnames(A), colnames(B))
rAB <- union(rownames(A), rownames(B))

A1 <- matrix(0, ncol=length(cAB), nrow=length(rAB), dimnames=list(rAB, cAB))
B1 <- A1

indxA <- outer(rAB, cAB, FUN=paste) %in% outer(rownames(A), colnames(A), FUN=paste) 
indxB <- outer(rAB, cAB, FUN=paste) %in% outer(rownames(B), colnames(B), FUN=paste)
A1[indxA] <- A
B1[indxB] <- B

A1+B1 #because it was mentioned to have `0` as missing values
#  a b c d e
#v 1 1 1 0 1
#w 1 1 0 2 0
#x 1 0 1 1 0
#y 0 1 2 1 0
#z 1 0 0 0 0

If you want to get the NA as missing values

A1 <- matrix(NA, ncol=length(cAB), nrow=length(rAB), dimnames=list(rAB, cAB))
B1 <- A1

A1[indxA] <- A
B1[indxB] <- B

indxNA <- is.na(A1) & is.na(B1)
A1[is.na(A1)!= indxNA] <- 0
B1[is.na(B1)!= indxNA] <- 0


A1+B1
#  a  b c d  e
#v 1  1 1 0  1
#w 1  1 0 2  0
#x 1  0 1 1 NA
#y 0  1 2 1  0
#z 1 NA 0 0  0

Or using reshape2

library(reshape2)
acast(rbind(melt(A), melt(B)), Var1~Var2, sum) #Inspired from the OP's idea
#  a b c d e
#v 1 1 1 0 1
#w 1 1 0 2 0
#x 1 0 1 1 0
#y 0 1 2 1 0
#z 1 0 0 0 0

data

A <- structure(c(1L, 1L, 1L, 0L, 1L, 1L, 0L, 1L, 1L, 0L, 1L, 1L, 0L, 
1L, 1L, 1L), .Dim = c(4L, 4L), .Dimnames = list(c("v", "w", "x", 
"y"), c("a", "b", "c", "d")))

B <- structure(c(0L, 0L, 0L, 1L, 0L, 0L, 1L, 0L, 0L, 1L, 0L, 0L, 1L, 
0L, 0L, 0L), .Dim = c(4L, 4L), .Dimnames = list(c("v", "w", "y", 
"z"), c("a", "c", "d", "e")))


来源:https://stackoverflow.com/questions/26042738/r-add-matrices-based-on-row-and-column-names

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!