Johannes
Johannes

Reputation: 1064

IGraph: network distance until stop node/vertex

I have an igraph network that contains two types of nodes, one set that describes my points/nodes of interest (NOI) and another set that act as barriers (B) in my network. Now I'd like to measure the total length of all edges that are connected starting from a specific NOI until a barrier is approached. Here a short example using a ring-shape in igraph:

set.seed(123)
g <- make_ring(10) %>%
  set_edge_attr("weight", value = rnorm(10,100,20))%>%
  set_vertex_attr("barrier", value = c(0,0,1,0,0,1,0,0,1,0))%>%
  set_vertex_attr("color", value = c("green","green","red",
                                       "green","green","red",
                                       "green","green","red","green"))

enter image description here

For example when starting from my node 1 (NOI, green) all edges until the nodes 9 and 3 are reachable (the nodes 9 and 3 are barriers B and block). Thus the total connected length of edges for NOI 1 is the sum of the lengths/weights of edges 1--2,2--3,1--10 and 10--9. The same value is true for node 10 as starting node. I the end I am interested in a list/dataframe of all NOI and their total length of reachable network. How to best proceed in R using igraph? Is there a built-in function in igraph?

Upvotes: 0

Views: 201

Answers (1)

MrFlick
MrFlick

Reputation: 206197

Here's one possible strategy. First, I set a name for each node so I will be preserved during graph transformations

V(g)$name = seq.int(vcount(g))

Now I drop all the barriers and split the graph up into separate connected nodes of interest that will all share the same length.

gd <- g %>% induced_subgraph(V(g)[V(g)$barrier==0]) %>% decompose()

Then We can write a helper function that takes a subgraph and finds all the incident edges for the nodes in the subgraph in the the original graph, extracts the weights, and sums them up

get_connected_length <- function(x) {
  incident_edges(g, V(g)$name %in% V(x)$name) %>% do.call("c", .) %>% unique() %>% .$weight %>% sum()
}

Now we apply the function to each of the subgraphs and extract the node names

n <- gd %>% Map(function(x) V(x)$name, .)
w <- gd %>% Map(get_connected_length, .)

And we can combine that data all together in a matrix

do.call("rbind", Map(cbind, n, w))
#      [,1]     [,2]
# [1,]    1 361.5366
# [2,]    2 361.5366
# [3,]   10 361.5366
# [4,]    4 335.1701
# [5,]    5 335.1701
# [6,]    7 318.2184
# [7,]    8 318.2184

Upvotes: 0

Related Questions