rtidygraph

How to manipulate a tidygraph object from a list of tidygraph objects inR?


If I have a list of tidygraph objects, I want to remove list elements based on some condition. For example, if I have a list of tidy graph object, like so:

nodes <- data.frame(name = c("Hadley", "David", "Romain", "Julia"))
edges <- data.frame(from = c(1, 1, 1, 2, 3, 3, 4, 4, 4),
                    to = c(2, 3, 4, 1, 1, 2, 1, 2, 3))
nodes_1 <- data.frame(name = c(NA))
edges_1 <- c()

tg <- tbl_graph(nodes = nodes, edges = edges)
tg_1 <- tbl_graph(nodes = nodes_1, edges = edges_1)

myList <- list(tg, tg_1)

Looking at the output of myList we can see that one of the tidygraph objects has no edges associated with it and the names column is NA.

> myList
[[1]]
# A tbl_graph: 4 nodes and 9 edges
#
# A directed simple graph with 1 component
#
# Node Data: 4 × 1 (active)
  name  
  <chr> 
1 Hadley
2 David 
3 Romain
4 Julia 
#
# Edge Data: 9 × 2
   from    to
  <int> <int>
1     1     2
2     1     3
3     1     4
# … with 6 more rows

[[2]]
# A tbl_graph: 1 nodes and 0 edges
#
# A rooted tree
#
# Node Data: 1 × 1 (active)
  name 
  <lgl>
1 NA   
#
# Edge Data: 0 × 2
# … with 2 variables: from <int>, to <int>

I was wondering if there is a way to iterate through the list and check if any of the tidygraph objects have no edge data or are NA (like in the above example) and remove this object from the list.

I know I could manually delete the list using myList <- myList[-2]. But I was looking for a more general solution for when I have a large amount of tidygraph objects in my list?


Solution

  • You can filter the list using igraph::gsize() which returns the edge count:

    library(tidygraph)
    library(igraph)
    
    Filter(function(x) gsize(x) > 0, myList)  # Filter(gsize, myList) also works but potentially less safe.
    
    # Or
    
    purrr::discard(myList, ~ gsize(.x) == 0)
    
    [[1]]
    # A tbl_graph: 4 nodes and 9 edges
    #
    # A directed simple graph with 1 component
    #
    # Node Data: 4 x 1 (active)
      name  
      <chr> 
    1 Hadley
    2 David 
    3 Romain
    4 Julia 
    #
    # Edge Data: 9 x 2
       from    to
      <int> <int>
    1     1     2
    2     1     3
    3     1     4
    # ... with 6 more rows