目前我的问题如下。我有一个很大的矩阵列表(大约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
我需要这些数字来识别社交网络中链接的强大功能。
这个问题对我来说似乎很复杂,所以我希望我能为你描述它很清楚:)
答案 0 :(得分:2)
我们创建了matrix
0(' mN'),其中包含输入矩阵的行名和列名的union
中的行名和列名,来自向量的length
的维度(' rn / cn')。我们将所有矩阵放在list
(lst
)中,循环遍历矩阵,更改' 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
。