顶点属性后的权重总和

时间:2018-06-28 13:22:47

标签: r igraph sna

在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数据框和顶点数据框。

3 个答案:

答案 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))