R: добавить матрицы на основе имен строк и столбцов

У меня есть две матрицы, которые я хочу суммировать на основе их имен строк и столбцов. Матрицы не обязательно будут иметь все общие строки и столбцы - некоторые из них могут отсутствовать в любой из матриц.

Например, рассмотрим две матрицы A и 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

Столбец e отсутствует в матрице A, а столбец b отсутствует в матрице B. Строка z отсутствует в матрице A, а строка x отсутствует в матрице B.

Суммарная таблица, которую я ищу:

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

Порядок строк и столбцов в окончательной матрице не имеет значения, пока матрица заполнена, то есть содержит все данные. Отсутствующие значения не обязательно должны быть «Na», вместо этого могут быть «0».

Я не уверен, есть ли способ сделать это без использования циклов for. Любая помощь приветствуется.

Мое решение

Мне удалось сделать это легко, преобразовав матрицы в фреймы данных, привязав фреймы данных по строкам, а затем преобразовав полученный фрейм данных обратно в матрицу. Похоже, это работает, но, возможно, кто-то может дважды проверить или сообщить мне, есть ли лучший способ.

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 выглядит так:

   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...

person James    schedule 25.09.2014    source источник
comment
Вы можете попробовать: library(reshape2); acast(rbind(melt(A), melt(B)), Var1~Var2, sum)   -  person akrun    schedule 25.09.2014
comment
Еще чище. Спасибо!   -  person James    schedule 25.09.2014


Ответы (1)


Может быть, вы можете попробовать:

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

Если вы хотите получить NA как отсутствующие значения

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

Или используя 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

данные

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")))
person akrun    schedule 25.09.2014
comment
Большое спасибо, акрун. Похоже, это тоже работает. Мне удалось кое-что выяснить с фреймами данных, которые мне подходят, как отмечалось выше в моем редактировании. - person James; 25.09.2014
comment
@ user3182448 Да, изменение формы набора данных является односторонним. - person akrun; 25.09.2014