3

This is an extension of the question posted previously: How to split an igraph into connected subgraphs?

I'll use the same example as the previous question

library(igraph)
g <- simplify(
  graph.compose(
    graph.ring(10), 
    graph.star(5, mode = "undirected")
  )
) + edge("7", "8")

enter image description here

The original user wanted to separate the network into the connected components. I would like to get a selection of the connected components based on the nodes, i.e. I want the networks containing node 9 and 2.

I think it could be done with decompose.graph(g) but I'm not sure how to put the two subgraphs back together. I need something like compose.graph(sub_g1, sub_g2).

Community
  • 1
  • 1
crysis405
  • 1,121
  • 2
  • 13
  • 26

2 Answers2

3

You can use graph.union function :

library(igraph)

g <- simplify(
  graph.compose(
    graph.ring(10), 
    graph.star(5, mode = "undirected")
  )
) + edge("7", "8")

# IMPORTANT ! set vertex names otherwise when you split in sub-graphs you won't be 
# able to recognize them(and don't forget as.character otherwise union will fail!)
g <- set.vertex.attribute(g,'name',index=V(g),as.character(1:vcount(g)))

# decompose the graph
sub.graphs  <- decompose.graph(g)

# search for the sub-graph indexes containing 2 and 9
sub.graph.indexes <- which(sapply(sub.graphs,function(g) any(V(g)$name %in% c('2','9'))))

# merge the desired subgraphs
merged <- do.call(graph.union,sub.graphs[sub.graph.indexes])

plot(merged)

enter image description here

digEmAll
  • 56,430
  • 9
  • 115
  • 140
2

Another way would be to use breadth-first search:

g <- set.vertex.attribute(g,'name',index=V(g),as.character(1:vcount(g)))
#select nodes of interest:
nodes.of.interest <- c(2,9)
#find subgraphs that contain selected nodes
sel.nodes  <- bfs(g ,root = nodes.of.interest ,unreachable = FALSE)$order
#remove additional nodes:
g.sub <- induced.subgraph(g , vids = sel.nodes[!is.na(sel.nodes)])
plot(g.sub)

enter image description here

David Heckmann
  • 2,899
  • 2
  • 20
  • 29
  • Ended up using your answer as `graph.union` creates a separate attribute for each merged graph making it messy. – crysis405 Mar 09 '17 at 12:07