R igraph: shortest path extraction -
this first time working graphs , r
igraph
package , need processing graph objects.
what want achieve:
given contact matrix extract shortest confident path between nodes. confident mean edge weights higher neighbouring edges.
examples:
a
m <- read.table(row.names = 1, header = true, text = " b c d e f 0 1 1 1 1 5 b 1 0 1 1e2 1e2 1 c 1 1 0 1 1 1 d 1 1e2 1 0 1e2 1 e 1 1e2 1 1e2 0 1 f 5 1 1 1 1 0") m <- as.matrix(m) ig <- graph.adjacency(m, mode = "undirected", weighted = true, diag = false) sp <- shortest.paths(ig, algorithm = "dijkstra")
in matrix m
there 1 cluster (clique?) between b-d-e
(ie., egde weights between nodes high). however, there weight between a
, f
getting cluster there, though edge weight low (only 5).
question a: how extract clusters have high edge weight? can transform contacts 0 m[which(m <= 5)] <- 0
, hope there more "mathy" solution in igraph
package.
b
m <- read.table(row.names = 1, header = true, text = " b c d e f 0 1 1 5 1 1 b 1 0 1 1e2 1e2 1 c 1 1 0 1 1 1 d 5 1e2 1 0 1e2 1 e 1 1e2 1 1e2 0 1 f 1 1 1 1 1 0") m <- as.matrix(m) ig <- graph.adjacency(m, mode = "undirected", weighted = true, diag = false) sp <- shortest.paths(ig, algorithm = "dijkstra")
in matrix m
there cluster between b-d-e
, there low weight between a
, b
- a
connected cluster.
question b: how not assign nodes cluster if edge weight low?
this first question here, if need clarification or better examples improve questions.
first, know when looking paths, igraph understands weights costs, i.e. on edges higher weight costs more travel, consider shorter paths lower sum weight. easy turn opposite, take reciprocal of weights (1 / e(ig)$weight
). between 2 vertices there might 1 shortest path, there more equally short paths. can of them (all_shortest_paths
), or tell igraph return 1 of shortests each pairs of vertices (shortest_paths
). each call of these methods returns paths 1 selected vertex, have paths between pairs, need call these once each vertex (ok, @ undirected graph, enough call half of vertices). formulate explained until point:
spaths <- lapply(v(ig), function(v){ all_shortest_paths(ig, v, weight = 1 / e(ig)$weight ) } )
here spaths
list of lists, access paths c
vertices this:
spaths$c$res [[1]] + 2/6 vertices, named: [1] c [[2]] + 2/6 vertices, named: [1] c b [[3]] + 1/6 vertex, named: [1] c [[4]] + 2/6 vertices, named: [1] c d [[5]] + 2/6 vertices, named: [1] c e [[6]] + 2/6 vertices, named: [1] c f spaths$c$res[[2]] # path `c` `b`, # vector of 2 vertices
note, third element c
itself, can either ignore it, or provide vector of other vertices to
parameter of all_shortest_paths
. also, in example shortest paths of length 1, if set example weight of b--e
1 instead of 100, see method works, , b
e
shortest path b-d-e
.
regarding second question, here not clear want achieve, how these clusters? if want find communities, i.e. more closely connected group of vertices, taking account edge weights, there many methods this, named cluster_[...]
or community.[...]
in igraph. example, if run fastgreedy method on graph, detect cluster mentioned:
fg <- fastgreedy.community(ig, weights = e(ig)$weight) igraph clustering fast greedy, groups: 2, mod: 0.059 + groups: $`1` [1] "a" "c" "f" $`2` [1] "b" "d" "e"
so here have b, d, e
cluster, connected higher weight edges. if run same method without weights, vertices belong 1 group (fastgreedy.community(ig, weights = null)
). note, @ community detection, igraph understands weights strength, vertices connected higher weight edges more cluster together, kind of opposite how works @ calculating paths.
Comments
Post a Comment