在R中,我有一个加权无向图作为igraph对象:
host = ${Influx.escape.stringLit(os.hostname())})
我想要做的是,以最优雅,最简单的方式,将某类顶点与另一类顶点的边权重求和,并将结果添加为顶点属性。
换句话说,对于每个与IGRAPH 60a5b9d UNW- 2777 19103 --
+ attr: name (v/c), label (v/c), nom (v/c), sigle (v/c), statut (v/c), champ (v/c), cp (v/c), info (v/c),
+ edges from 60a5b9d (vertex names):
[1] 0--35 1--9 1--199 1--484 2--171 2--483 2--978 2--3564 3--9 3--1464 3--1474 3--2981 4--75 6--18 6--25
[16] 6--28 6--33 6--64 6--65 6--71 6--86 6--87 6--101 6--104 6--113 6--118 6--144 6--166 6--182 6--183
+ ... omitted several edges
匹配的顶点,我不确定如何列出所有与V(net)$attribute == "value"
匹配的顶点的边,然后求和权重。而且我不知道igraph是执行此类操作的最佳选择,还是我应该使用Edge数据框和顶点数据框。
答案 0 :(得分:0)
我认为distances
函数及其表亲是您所需要的。我会指出,如果两个节点之间有多个路径,我不确定返回的距离是多少
小型MWE:
library(igraph)
g <- barabasi.game(10, directed = FALSE)
E(g)$weight <- runif(ecount(g), min = 1,max = 5)
plot(g, edge.width=E(g)$weight)
distances(g, V(g)[1], V(g)[c(3,5,8)])
# [,1] [,2] [,3]
# [1,] 3.78849 6.174016 5.652662
sum(distances(g, V(g)[1], V(g)[c(3,5,8)]))
# [1] 15.61517
答案 1 :(得分:0)
由于我不知道如何使用igraph进行此操作,因此我使用数据帧和dplyr进行了此操作。这是我的代码,如果可以在某些时候帮助别人的话:
# transform igraph object in two data frames and remove NAs
res_df <- igraph::as_data_frame(res, 'both')
res_v <- res_df$vertices
res_e <- res_df$edges
res_v[is.na(res_v)] <- 0
res_e[is.na(res_e)] <- 0
# generate two vectors listing ids of the nodes following critera 1 and criteria 2
crit1_id <- res_v %>% filter(criteria == "value1") %>% .$name %>% as.numeric()
crit2_id <- res_v %>% filter(criteria == "value2") %>% .$name %>% as.numeric()
# generate an edge list listing ties between any id from crit1_id to any id from crit2_id
list_edge_1 <- res_e %>% filter(from %in% crit1_id & to %in% crit2_id)
list_edge_2 <- res_e %>% filter(from %in% crit2_id & to %in% crit1_id)
list_edge <- rbind(list_edge_1, list_edge_2)
# for each node in crit1_id, list direct edges to any node in crit2_id and store the weights in a vector, then add the sum of weights as a node attribute
for (n in crit1_id) {
s <- list_edge %>% filter(from == n | to == n) %>% .$weight
res_v$new_attribute[res_v$name == n] <- sum(s)
}
# make a new igraph object if you need
new_res <- graph_from_data_frame(res_e,
directed = F,
vertices = res_v)
答案 2 :(得分:0)
您确实可以使用igraph
完成此操作,
请参考此代码中的注释:
library(igraph)
# sample
net <- make_empty_graph(3L, FALSE) %>%
set_vertex_attr(name = "myattr", value = c("a", "b", "b")) %>%
add_edges(c(1L, 2L), weight = 10)
vertices <- V(net)
a_vertices <- which(vertices$myattr == "a")
b_vertices <- which(vertices$myattr == "b")
# each column of edge_list will have a potential pair of nodes
edge_list <- t(as.matrix(expand.grid(a_vertices, b_vertices)))
# this will get the edge ID corresponding to each pair
edges <- get.edge.ids(net, edge_list)
# if the edge does not exist, its ID will be 0
edges <- edges[edges != 0L]
# the sum of weights from all existing edges that fulfill the condition
total <- sum(edge_attr(net, "weight", edges))