将几个节点向量合并到一个边列表中并将它们转换为邻接矩阵
Merging several vectors of nodes into an edgelist and convert them to an adjacency matrix
我想将多个关系圈(由 id
的列表组成)映射到一个大的邻接矩阵中。我的数据看起来像这样
circle_1 = c(1, 3, 5)
circle_2 = c(17, 22, 35, 49)
circle_3 = c(2, 9)
circle_4 = c(12, 28, 33)
circle_5 = c(1, 3, 8, 16, 40)
d_mat = matrix(ncol = 2)
for (i in 1:5) {
#extract id from list
dat = get(paste("circle", i, sep="_"))
#convert to edgelist, each pair is unique
dat_t = t(combn(dat, 2))
#rbind edge list together
edge_list <- rbind(d_mat, dat_t)
}
然而,输出edge_list
仅returns来自最后一次迭代(circle_5
)的边缘列表,前三个被覆盖。
此外,假设这五个圆圈是从一组 50 个人中抽取的,我如何将这些边列表的值映射到 50 x 50 邻接矩阵的相应单元格? (我想 make_graph
和 as_adjacency_matrix
中的函数 igraph
应该可以解决问题,但我现在不知道怎么做)
此外,对于重叠成员,例如 circle_1
和 circle_5
中的 (1, 3),这意味着 1 和 3 在这个 50 人网络中链接了两次。如何聚合此计数频率并将邻接矩阵转换为加权矩阵?
您可以像开始时那样合并边列表,然后直接创建矩阵。
circle_1 = c(1, 3, 5)
circle_2 = c(17, 22, 35, 49)
circle_3 = c(2, 9)
circle_4 = c(12, 28, 33)
circle_5 = c(1, 3, 8, 16, 40)
# lets put all the circles in a list for convenience
circles <- list(circle_1, circle_2, circle_3,
circle_4, circle_5)
# we will lapply along the list, get the complete set of
# edges with combn, and then rbind all the resulting
# structures together
edge_list <- do.call(rbind, lapply(circles, function(circ){t(combn(circ, 2))}))
# we convert to a data.frame and set the factor levels
# such that R knows these are nodes from a set of 50 nodes
edge_list <- data.frame(from = factor(edge_list[,1], levels=1:50),
to = factor(edge_list[,2], levels=1:50))
# take a look
head(edge_list)
#> from to
#> 1 1 3
#> 2 1 5
#> 3 3 5
#> 4 17 22
#> 5 17 35
#> 6 17 49
# we can just use table to make the adjacency matrix. R will create
# a row/column for each level of the factor. We look at the first
# 6x6 entries
table(edge_list)[1:6,1:6] # luckily entry (1,3) = 2 as we hoped
#> to
#> from 1 2 3 4 5 6
#> 1 0 0 2 0 1 0
#> 2 0 0 0 0 0 0
#> 3 0 0 0 0 1 0
#> 4 0 0 0 0 0 0
#> 5 0 0 0 0 0 0
#> 6 0 0 0 0 0 0
这个邻接矩阵是上三角矩阵。如果您希望邻接矩阵是对称的以反映无向图,您可以使用 adj.mat[lower.tri(adj.mat)] <- adj.mat[upper.tri(adj.mat)]
.
将矩阵的上下三角形设置为相等
如果您希望矩阵只是二进制的(而不是在不同的圈子中记录多个链接)只需 运行 通过 ifelse 语句:
# to convert to purely binary
adj.mat <- table(edge_list)
adj.mat.bin <- ifelse(adj.mat>1, 1, adj.mat)
adj.mat.bin[1:6,1:6]
#> to
#> from 1 2 3 4 5 6
#> 1 0 0 1 0 1 0
#> 2 0 0 0 0 0 0
#> 3 0 0 0 0 1 0
#> 4 0 0 0 0 0 0
#> 5 0 0 0 0 0 0
#> 6 0 0 0 0 0 0
由 reprex package (v0.2.1)
创建于 2018-11-16
我从@gfgm 那里借用了顶点列表('circles')并使用了igraph
函数。
用 lapply
遍历顶点列表。对于每组顶点,创建一个完整图 (make_full_graph
),其中顶点数 n
等于向量的长度。设置顶点的名称 (V(g)$name
)。转换为 'edge list' (as_edgelist
)。 rbind
结果矩阵。
library(igraph)
m <- do.call(rbind, lapply(circles, function(vert){
g <- make_full_graph(n = length(vert))
V(g)$name <- vert
as_edgelist(g)
}))
设置factor
层'from'和'to'顶点,并使用table
(类似于@gfgm)
tt <- table(factor(m[ , 1], levels = 1:50),
factor(m[ , 2], levels = 1:50))
t[1:8, 1:16]
# 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
# 1 0 0 2 0 1 0 0 1 0 0 0 0 0 0 0 1
# 2 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
# 3 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 1
# 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
# 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
# 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
# 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
# 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
我想将多个关系圈(由 id
的列表组成)映射到一个大的邻接矩阵中。我的数据看起来像这样
circle_1 = c(1, 3, 5)
circle_2 = c(17, 22, 35, 49)
circle_3 = c(2, 9)
circle_4 = c(12, 28, 33)
circle_5 = c(1, 3, 8, 16, 40)
d_mat = matrix(ncol = 2)
for (i in 1:5) {
#extract id from list
dat = get(paste("circle", i, sep="_"))
#convert to edgelist, each pair is unique
dat_t = t(combn(dat, 2))
#rbind edge list together
edge_list <- rbind(d_mat, dat_t)
}
然而,输出edge_list
仅returns来自最后一次迭代(circle_5
)的边缘列表,前三个被覆盖。
此外,假设这五个圆圈是从一组 50 个人中抽取的,我如何将这些边列表的值映射到 50 x 50 邻接矩阵的相应单元格? (我想 make_graph
和 as_adjacency_matrix
中的函数 igraph
应该可以解决问题,但我现在不知道怎么做)
此外,对于重叠成员,例如 circle_1
和 circle_5
中的 (1, 3),这意味着 1 和 3 在这个 50 人网络中链接了两次。如何聚合此计数频率并将邻接矩阵转换为加权矩阵?
您可以像开始时那样合并边列表,然后直接创建矩阵。
circle_1 = c(1, 3, 5)
circle_2 = c(17, 22, 35, 49)
circle_3 = c(2, 9)
circle_4 = c(12, 28, 33)
circle_5 = c(1, 3, 8, 16, 40)
# lets put all the circles in a list for convenience
circles <- list(circle_1, circle_2, circle_3,
circle_4, circle_5)
# we will lapply along the list, get the complete set of
# edges with combn, and then rbind all the resulting
# structures together
edge_list <- do.call(rbind, lapply(circles, function(circ){t(combn(circ, 2))}))
# we convert to a data.frame and set the factor levels
# such that R knows these are nodes from a set of 50 nodes
edge_list <- data.frame(from = factor(edge_list[,1], levels=1:50),
to = factor(edge_list[,2], levels=1:50))
# take a look
head(edge_list)
#> from to
#> 1 1 3
#> 2 1 5
#> 3 3 5
#> 4 17 22
#> 5 17 35
#> 6 17 49
# we can just use table to make the adjacency matrix. R will create
# a row/column for each level of the factor. We look at the first
# 6x6 entries
table(edge_list)[1:6,1:6] # luckily entry (1,3) = 2 as we hoped
#> to
#> from 1 2 3 4 5 6
#> 1 0 0 2 0 1 0
#> 2 0 0 0 0 0 0
#> 3 0 0 0 0 1 0
#> 4 0 0 0 0 0 0
#> 5 0 0 0 0 0 0
#> 6 0 0 0 0 0 0
这个邻接矩阵是上三角矩阵。如果您希望邻接矩阵是对称的以反映无向图,您可以使用 adj.mat[lower.tri(adj.mat)] <- adj.mat[upper.tri(adj.mat)]
.
如果您希望矩阵只是二进制的(而不是在不同的圈子中记录多个链接)只需 运行 通过 ifelse 语句:
# to convert to purely binary
adj.mat <- table(edge_list)
adj.mat.bin <- ifelse(adj.mat>1, 1, adj.mat)
adj.mat.bin[1:6,1:6]
#> to
#> from 1 2 3 4 5 6
#> 1 0 0 1 0 1 0
#> 2 0 0 0 0 0 0
#> 3 0 0 0 0 1 0
#> 4 0 0 0 0 0 0
#> 5 0 0 0 0 0 0
#> 6 0 0 0 0 0 0
由 reprex package (v0.2.1)
创建于 2018-11-16我从@gfgm 那里借用了顶点列表('circles')并使用了igraph
函数。
用 lapply
遍历顶点列表。对于每组顶点,创建一个完整图 (make_full_graph
),其中顶点数 n
等于向量的长度。设置顶点的名称 (V(g)$name
)。转换为 'edge list' (as_edgelist
)。 rbind
结果矩阵。
library(igraph)
m <- do.call(rbind, lapply(circles, function(vert){
g <- make_full_graph(n = length(vert))
V(g)$name <- vert
as_edgelist(g)
}))
设置factor
层'from'和'to'顶点,并使用table
(类似于@gfgm)
tt <- table(factor(m[ , 1], levels = 1:50),
factor(m[ , 2], levels = 1:50))
t[1:8, 1:16]
# 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
# 1 0 0 2 0 1 0 0 1 0 0 0 0 0 0 0 1
# 2 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
# 3 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 1
# 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
# 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
# 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
# 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
# 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1