将矩阵列表合并为大矩阵(总结其值)

Merge a list of matrices into big matrix(summarizing its values)

我现在的问题如下。我有一大堆矩阵(大约 1600 个)。实际上它是具有不同大小(从 2:2 到 5:5)的派系的邻接矩阵。 这是 2 个矩阵的示例

第一

            name1      name2      name3
name1          1          1          1 
name2          1          1          1
name3          1          1          1

第二个

           name4       name5      name6      name7
name4          1          1          1          1
name5          1          1          1          1
name6          1          1          1          1
name7          1          1          1          1

我需要将这个矩阵合并成一个更大的矩阵 并拥有类似的东西:

           name1    name2     name3     name4     name5     name6    name7
name1          1          1          1       0         0        0        0
name2          1          1          1       0         0        0        0
name3          1          1          1       0         0        0        0
name4          0          0          0       1         1        1        1
name5          0          0          0       1         1        1        1
name6          0          0          0       1         1        1        1
name7          0          0          0       1         1        1        1

但这还不是全部。如果有类似的集团(例如示例中的第一个集团),或者另一个包含旧名称的集团,我希望它的值用大矩阵中的值进行总结。得到如下形式的矩阵:

           name1    name2     name3     name4     name5     name6    name7
name1          2          2          2       0         0        0        0
name2          2          2          2       0         0        0        0
name3          2          2          2       0         0        0        0
name4          0          0          0       1         1        1        1
name5          0          0          0       1         1        1        1
name6          0          0          0       1         1        1        1
name7          0          0          0       1         1        1        1

我将需要这些数字来识别我的社交网络中链接的力量。

这个问题对我来说似乎很复杂,所以我希望我对你描述得足够清楚:)

我们创建一个 matrix 的 0 ('mN'),其中行名和列名来自输入矩阵的行名和列名的 union,维度来自向量的 length ('rn/cn')。我们将所有的矩阵放在一个listlst)中,遍历矩阵,将各个矩阵的row/column索引对应的'mN'的值改为1,然后sum对应的list个元素有Reduce.

lst <- list(m1, m2)
rn <- Reduce(union, lapply(lst, rownames))
cn <- Reduce(union, lapply(lst, colnames))
mN <- matrix(0, ncol=length(cn), nrow=length(rn), dimnames=list(rn, cn))

Reduce(`+`,lapply(lst, function(x) {mN[rownames(x), colnames(x)] <- 1; mN})) 
#      name1 name2 name3 name4 name5 name6 name7
#name1     1     1     1     0     0     0     0
#name2     1     1     1     0     0     0     0
#name3     1     1     1     0     0     0     0
#name4     0     0     0     1     1     1     1
#name5     0     0     0     1     1     1     1
#name6     0     0     0     1     1     1     1
#name7     0     0     0     1     1     1     1

如果多个元素有匹配的 row/column 名称,这将执行 sum

lst <- list(m1, m2, m1)

并重复上述步骤

#      name1 name2 name3 name4 name5 name6 name7
#name1     2     2     2     0     0     0     0
#name2     2     2     2     0     0     0     0
#name3     2     2     2     0     0     0     0
#name4     0     0     0     1     1     1     1
#name5     0     0     0     1     1     1     1
#name6     0     0     0     1     1     1     1
#name7     0     0     0     1     1     1     1

数据

m1 <- structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Dim = c(3L, 
3L), .Dimnames = list(c("name1", "name2", "name3"), c("name1", 
"name2", "name3")))

m2 <- structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L), .Dim = c(4L, 4L), .Dimnames = list(c("name4", "name5", 
"name6", "name7"), c("name4", "name5", "name6", "name7")))

像下面这样的事情应该做:

# Toy data
m1 <- matrix(1, 4, 4, dimnames = list(paste0("name", 1:4), paste0("name", 1:4)))
m2 <- matrix(1, 5, 5, dimnames = list(paste0("name", 5:9), paste0("name", 5:9)))

# Create "your list"
mlist <- list(m1, m2, m1)

策略是用所有 nodes/names 制作一个矩阵,然后将派系添加到此:

# Get all names
nms <- unique(unlist(lapply(mlist, colnames)))

# Create matrix to hold values
ans <- matrix(0, length(nms), length(nms), dimnames = list(nms, nms))

# Fill in values:
for (i in seq_along(mlist)) {
  n <- colnames(mlist[[i]])
  ans[n, n] <- ans[n, n] + mlist[[i]]
}
print(ans)
#      name1 name2 name3 name4 name5 name6 name7 name8 name9
#name1     2     2     2     2     0     0     0     0     0
#name2     2     2     2     2     0     0     0     0     0
#name3     2     2     2     2     0     0     0     0     0
#name4     2     2     2     2     0     0     0     0     0
#name5     0     0     0     0     1     1     1     1     1
#name6     0     0     0     0     1     1     1     1     1
#name7     0     0     0     0     1     1     1     1     1
#name8     0     0     0     0     1     1     1     1     1
#name9     0     0     0     0     1     1     1     1     1

这也适用于重叠的派系。

EDIT 循环可以被类似的东西隐藏起来:

ans <- matrix(0, length(nms), length(nms), dimnames = list(nms, nms))
lapply(mlist, function(m) {n <- rownames(m); ans[n,n] <<- ans[n,n] + m})
print(ans)
# .. as above ...

但是,可能更符合 R-ideomatic 的是:

ans <- matrix(0, length(nms), length(nms), dimnames = list(nms, nms))
tmp <- lapply(mlist, function(m) {ans[rownames(m),colnames(m)] <-  m; ans})
print(Reduce("+", tmp))
# .. as above ...

以与@akrun 的回答类似的方式使用 Reduce