将矩阵列表合并为大矩阵(总结其值)
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')。我们将所有的矩阵放在一个list
(lst
)中,遍历矩阵,将各个矩阵的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
。
我现在的问题如下。我有一大堆矩阵(大约 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')。我们将所有的矩阵放在一个list
(lst
)中,遍历矩阵,将各个矩阵的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
。