在 igraph 中使用 contract_vertices() 和社区函数时,是否有更简单的方法来 return 边缘值?
Is there a simpler way to return edge values when using contract_vertices() and community functions in igraph?
我有一张社区图。我想要图中一个社区和所有其他节点之间的所有边的边权重。我需要单独的权重,因为我想对每个边缘权重进行计算(将它们平方,就其价值而言)。我和 and this 有点距离,但真的很尴尬。
这是我试过的:
library(igraph)
## create example graph
g1 <- graph.full(5)
V(g1)$name <- 1:5
g2 <- graph.full(5)
V(g2)$name <- 6:10
g3 <- graph.ring(5)
V(g3)$name <- 11:15
g <- g1 %du% g2 %du% g3 + edge('1', '6') + edge('1', '11')
E(g)$weight <- c(1:27)
# determine community structure
cl <- cluster_louvain(g)
V(g)$name <- membership(cl)
# contract the graph
cg <- contract.vertices(graph = g,
mapping = membership(cl))
cg2 <- simplify(cg)
contract.vertices() 保留边属性。要提取社区与所有其他节点(社区节点内除外)之间的边权重并对权重执行一些计算,我可以这样做:
# edges weights linking community 1 and community 2
E(cg)[ V(cg)[1] %--% V(cg)[2]]$weight
#> [1] 1 2 3 4
# edges weights linking community 1 and community 3
E(cg)[ V(cg)[1] %--% V(cg)[3]]$weight
#> [1] 26
bind_rows(
tibble(one_two_edges = E(cg)[ V(cg)[2] %--% V(cg)[1]]$weight) %>%
mutate(summed_square_edge_weight = one_two_edges^2) %>%
summarize_all(sum) %>%
select(-one_two_edges)
,
tibble(one_three_edges = E(cg)[ V(cg)[1] %--% V(cg)[3]]$weight) %>%
mutate(summed_square_edge_weight = one_three_edges^2) %>%
summarize_all(sum) %>%
select(-one_three_edges)
)
#> # A tibble: 2 × 1
#> summed_square_edge_weight
#> <dbl>
#> 1 30
#> 2 676
我知道这很笨拙,但我不知道如何简化它。我正在寻找的是这样的东西:
tibble(
community_links = c("com_1_to_com_2", "com_1_to_com_3"),
summed_square_edge_weight = c(30, 676))
#> # A tibble: 2 × 2
#> community_links summed_square_edge_weight
#> <chr> <dbl>
#> 1 com_1_to_com_2 30
#> 2 com_1_to_com_3 676
关于如何更简单地获得这些结果的建议?
由 reprex package (v2.0.1)
于 2022-04-23 创建
你实际上正在接近它,我认为 combn
可以帮助你
do.call(
rbind,
combn(
vcount(cg),
2,
function(k) {
data.frame(
community_links = paste0(paste0("com_", k), collapse = "_to_"),
summed_square_edge_weight = sum((E(cg)[V(cg)[k[1]] %--% V(cg)[k[2]]]$weight)^2)
)
},
simplify = FALSE
)
)
这给出了
community_links summed_square_edge_weight
1 com_1_to_com_2 30
2 com_1_to_com_3 676
3 com_2_to_com_3 0
在 igraph
仔细研究之后,事实证明这是可能的:igraph::get.data.frame()
returns 一个带有收缩顶点边权重的边列表(这里用 tibble::as_tibble()
。结果 contract.vertices()
函数中的 vertex.attr.comb()
参数需要设置为保留先前分配的名称顶点属性的内容。我没有对平方求和只是为了显示返回值.
cg <- contract.vertices(graph = g,
mapping = membership(cl),
vertex.attr.comb = "min")
as_tibble(as_long_data_frame(cg),
.name_repair = "universal") %>%
select(from:weight) %>%
filter(from != to) %>%
mutate(sq_weight = weight^2)
#> # A tibble: 5 × 4
#> from to weight sq_weight
#> <dbl> <dbl> <dbl> <dbl>
#> 1 1 2 1 1
#> 2 1 2 2 4
#> 3 1 2 3 9
#> 4 1 2 4 16
#> 5 1 3 26 676
我有一张社区图。我想要图中一个社区和所有其他节点之间的所有边的边权重。我需要单独的权重,因为我想对每个边缘权重进行计算(将它们平方,就其价值而言)。我和
这是我试过的:
library(igraph)
## create example graph
g1 <- graph.full(5)
V(g1)$name <- 1:5
g2 <- graph.full(5)
V(g2)$name <- 6:10
g3 <- graph.ring(5)
V(g3)$name <- 11:15
g <- g1 %du% g2 %du% g3 + edge('1', '6') + edge('1', '11')
E(g)$weight <- c(1:27)
# determine community structure
cl <- cluster_louvain(g)
V(g)$name <- membership(cl)
# contract the graph
cg <- contract.vertices(graph = g,
mapping = membership(cl))
cg2 <- simplify(cg)
contract.vertices() 保留边属性。要提取社区与所有其他节点(社区节点内除外)之间的边权重并对权重执行一些计算,我可以这样做:
# edges weights linking community 1 and community 2
E(cg)[ V(cg)[1] %--% V(cg)[2]]$weight
#> [1] 1 2 3 4
# edges weights linking community 1 and community 3
E(cg)[ V(cg)[1] %--% V(cg)[3]]$weight
#> [1] 26
bind_rows(
tibble(one_two_edges = E(cg)[ V(cg)[2] %--% V(cg)[1]]$weight) %>%
mutate(summed_square_edge_weight = one_two_edges^2) %>%
summarize_all(sum) %>%
select(-one_two_edges)
,
tibble(one_three_edges = E(cg)[ V(cg)[1] %--% V(cg)[3]]$weight) %>%
mutate(summed_square_edge_weight = one_three_edges^2) %>%
summarize_all(sum) %>%
select(-one_three_edges)
)
#> # A tibble: 2 × 1
#> summed_square_edge_weight
#> <dbl>
#> 1 30
#> 2 676
我知道这很笨拙,但我不知道如何简化它。我正在寻找的是这样的东西:
tibble(
community_links = c("com_1_to_com_2", "com_1_to_com_3"),
summed_square_edge_weight = c(30, 676))
#> # A tibble: 2 × 2
#> community_links summed_square_edge_weight
#> <chr> <dbl>
#> 1 com_1_to_com_2 30
#> 2 com_1_to_com_3 676
关于如何更简单地获得这些结果的建议?
由 reprex package (v2.0.1)
于 2022-04-23 创建你实际上正在接近它,我认为 combn
可以帮助你
do.call(
rbind,
combn(
vcount(cg),
2,
function(k) {
data.frame(
community_links = paste0(paste0("com_", k), collapse = "_to_"),
summed_square_edge_weight = sum((E(cg)[V(cg)[k[1]] %--% V(cg)[k[2]]]$weight)^2)
)
},
simplify = FALSE
)
)
这给出了
community_links summed_square_edge_weight
1 com_1_to_com_2 30
2 com_1_to_com_3 676
3 com_2_to_com_3 0
在 igraph
仔细研究之后,事实证明这是可能的:igraph::get.data.frame()
returns 一个带有收缩顶点边权重的边列表(这里用 tibble::as_tibble()
。结果 contract.vertices()
函数中的 vertex.attr.comb()
参数需要设置为保留先前分配的名称顶点属性的内容。我没有对平方求和只是为了显示返回值.
cg <- contract.vertices(graph = g,
mapping = membership(cl),
vertex.attr.comb = "min")
as_tibble(as_long_data_frame(cg),
.name_repair = "universal") %>%
select(from:weight) %>%
filter(from != to) %>%
mutate(sq_weight = weight^2)
#> # A tibble: 5 × 4
#> from to weight sq_weight
#> <dbl> <dbl> <dbl> <dbl>
#> 1 1 2 1 1
#> 2 1 2 2 4
#> 3 1 2 3 9
#> 4 1 2 4 16
#> 5 1 3 26 676