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

时间:2015-09-28 13:55:25

标签: r matrix sna

目前我的问题如下。我有一个很大的矩阵列表(大约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

但这不是全部。如果有类似的clique(如示例中的第一个)或另一个包含旧名称的clique,我希望它的值可以用大矩阵中的值进行汇总。并获得以下形式的矩阵:

           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

我需要这些数字来识别社交网络中链接的强大功能。

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

2 个答案:

答案 0 :(得分:2)

我们创建了matrix 0(' mN'),其中包含输入矩阵的行名和列名的union中的行名和列名,来自向量的length的维度(' rn / cn')。我们将所有矩阵放在listlst)中,循环遍历矩阵,更改' 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

如果有多个元素匹配的行/列名称,这将执行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")))

答案 1 :(得分:1)

以下内容应该这样做:

# 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)

策略是制作一个包含所有节点/名称的矩阵,然后将派系添加到此:

# 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

这也适用于重叠派系。

编辑循环可以被隐藏起来:

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