I have matrices of varying dimensions such as:
a <- read.table(text = "
Si N1 N2 A1 A2 A3 A4 A5 Z1 Z2 Z3 Z5 IN M S
Si 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0
N1 0 1 0 1 1 1 1 1 0 0 0 0 0 0 0
N2 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0
A1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0
A2 0 1 1 0 0 0 0 0 0 0 1 1 0 1 0
A3 1 1 0 0 0 0 0 0 1 0 0 0 0 0 0
A4 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0
A5 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0
Z1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0
Z2 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1
Z3 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0
Z5 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0
IN 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0
M 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0
S 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1
", header = TRUE)
and:
b <- read.table(text = "
Si N1 N2 A1 A2 A3 A4 A5 Z1 Z2 Z3 Z5 D IN M O P
Si 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
N1 0 1 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0
N2 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
A1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1
A2 0 1 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0
A3 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
A4 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0
A5 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0
Z1 0 0 0 0 0 1 0 0 1 1 0 0 0 0 0 0 0
Z2 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0
Z3 0 0 0 0 1 0 0 0 0 1 1 0 1 0 0 0 0
Z5 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0
D 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0
IN 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0
M 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1
O 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0
P 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0
", header = TRUE)
and I'm trying to add them so that variables missing from either are included in the result.
I've found a helpful previous post: How to aggregate matrices which have different dimensions? [R] and have tried the codes, but the problem remains that my variable names change and that some are missing.
This code was the closest:
sum_mat = function(a, b){
temp = matrix(data = 0, nrow = max(nrow(a), nrow(b)), ncol = max(ncol(a), ncol(b)))
temp_a = temp
temp_a[1:nrow(a), 1:ncol(a)] = a
temp_b = temp
temp_b[1:nrow(b), 1:ncol(b)] = b
temp_a + temp_b
}
c = sum_mat(a, b)
c
but the resulting matrix is 17X17 and should be 18 X 18 because the 'S' variable from a is missing from b and needs to be included to look like this:
c <- read.table(text = "
Si N1 N2 A1 A2 A3 A4 A5 Z1 Z2 Z3 Z5 D IN M O P S
Si 2 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0
N1 0 2 0 2 2 2 2 2 0 0 0 0 0 0 0 0 0 0
N2 0 0 2 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0
A1 0 2 0 0 0 0 0 0 0 2 0 0 0 0 1 0 1 0
A2 0 2 2 0 0 0 0 0 0 0 2 2 1 0 1 0 0 0
A3 2 1 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0
A4 0 2 0 0 0 0 2 0 0 0 0 0 0 0 0 1 0 0
A5 0 2 0 0 0 0 0 1 0 0 0 0 0 2 0 0 0 0
Z1 0 0 0 0 0 2 0 0 2 1 0 0 0 0 0 0 0 0
Z2 0 0 0 2 0 0 0 0 0 1 0 0 0 0 0 0 0 1
Z3 0 0 0 0 2 0 0 0 0 1 2 0 1 0 0 0 0 0
Z5 0 0 0 0 2 0 0 0 0 0 0 2 0 1 0 0 0 0
D 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0
IN 0 0 0 0 0 0 0 2 0 0 0 1 0 1 0 0 0 0
M 0 0 0 1 1 0 0 0 0 0 0 0 0 0 1 0 1 0
O 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0
P 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0
S 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1
", header = TRUE)
If the row names match the column names:
matadd <- function(a, b) {
nms <- unique(c(colnames(b), colnames(a)))
ia <- match(colnames(a), nms, nomatch = 0L)
ib <- match(colnames(b), nms, nomatch = 0L)
m <- matrix(vector(typeof(a), 1), length(nms), length(nms), 0, list(nms, nms))
m[ia, ia] <- a
m[ib, ib] <- m[ib, ib] + b
m
}
matadd(as.matrix(a), as.matrix(b))
#> Si N1 N2 A1 A2 A3 A4 A5 Z1 Z2 Z3 Z5 D IN M O P S
#> Si 2 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0
#> N1 0 2 0 2 2 2 2 2 0 0 0 0 0 0 0 0 0 0
#> N2 0 0 2 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0
#> A1 0 2 0 0 0 0 0 0 0 2 0 0 0 0 1 0 1 0
#> A2 0 2 2 0 0 0 0 0 0 0 2 1 1 0 1 0 0 0
#> A3 2 1 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0
#> A4 0 2 0 0 0 0 2 0 0 0 0 0 0 0 0 1 0 0
#> A5 0 2 0 0 0 0 0 1 0 0 0 0 0 2 0 0 0 0
#> Z1 0 0 0 0 0 2 0 0 2 1 0 0 0 0 0 0 0 0
#> Z2 0 0 0 2 0 0 0 0 0 1 0 0 0 0 0 0 0 1
#> Z3 0 0 0 0 2 0 0 0 0 1 2 0 1 0 0 0 0 0
#> Z5 0 0 0 0 1 0 0 0 0 0 0 2 0 1 0 0 0 0
#> D 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0
#> IN 0 0 0 0 0 0 0 2 0 0 0 1 0 1 0 0 0 0
#> M 0 0 0 1 1 0 0 0 0 0 0 0 0 0 2 0 1 0
#> O 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0
#> P 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0
#> S 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1