Search code examples
rigraphsubgraph

Error with subgraph in igraph package


I want to get the subgraph of all the cycles in a graph. I tried the code below

 for (i in 1:length(cycles)){
    vids<-as.numeric(unlist(cycles[[i]]))
    subgraph<- induced.subgraph(graph, vids)
 }

But it throws and error as below:

Error in .Call("R_igraph_induced_subgraph", graph, vids - 1, impl, PACKAGE = "igraph") : 
  At iterators.c:759 : Cannot create iterator, invalid vertex id, Invalid vertex id

I found that the code works with the second element in the cycles list which is shorter but not the first one. So if I try this will work,

subgraph<- induced.subgraph(g, c(3,4))

but not

subgraph<- induced.subgraph(g, c(26, 2, 30, 29, 25, 9, 27, 13, 14, 8, 23, 20, 19, 17, 12, 11, 24, 21, 6, 28, 15,3,4))

Also, any suggestions to substitute the for loop are welcomed.

A reproducible example:

    library(igraph)
    graph<-graph(c(1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,16,
           16,17,17,18,18,19,19,20,20,21,21,1,22,23,23,22),directed=T)
    V(graph)$name<-c(26, 2, 30, 29, 25, 9, 27, 13, 14, 8, 23, 20, 19, 17, 12, 11, 
             24, 21, 6, 28, 15,3,4)

    cycles<-list(list(26L, 2L, 30L, 29L, 25L, 9L, 27L, 13L, 14L, 8L, 23L, 
        20L, 19L, 17L, 12L, 11L, 24L, 21L, 6L, 28L, 15L), list(4L, 
        3L))

Solution

  • If you pass a number as a vertex id to the induced.subgraph function, it will be accessing the vertices by number (in your graph numbers 1 through 23), leading to the "Invalid vertex ID" error due to indices like 26, 29, and 30. You want to actually refer to vertices by name, which you can do by passing a string instead of a number:

    for (i in 1:length(cycles)){
      vids <- as.character(unlist(cycles[[i]]))
      subgraph<- induced.subgraph(graph, vids)
      plot(subgraph)
    }
    

    Now you have successfully extracted the two subgraphs:

    enter image description here

    enter code here

    There's no way to avoid looping through your list to generate the subgraphs, though you could hide the loop with something like the lapply function:

    subgraphs <- lapply(cycles, function(x) induced.subgraph(graph, as.character(unlist(x))))
    

    Now subgraphs is a list of graphs, one for each cycle. They can be accessed with subgraphs[[1]] and subgraphs[[2]] in your case.