Search code examples
rlistuniqueigraph

How to return unique sub-elements of igraph list in R


I have a list walks that came from the igraph object:

> walks
[[1]]
+ 3/10 vertices, named, from d1edbf2:
[1] C O D

[[2]]
+ 3/10 vertices, named, from d1edbf2:
[1] C O J

[[3]]
+ 3/10 vertices, named, from d1edbf2:
[1] C O N

[[4]]
+ 3/10 vertices, named, from d1edbf2:
[1] C O N

I need to return unique sub-elements of list. Expected result is:

[[1]]
[1] C O D

[[2]]
[1] C O J

[[3]]
[1] C O N

I try to use the unique() function on a toy example list:

list1 = list(c("C", "O", "D"), c("C", "O", "J"), c("C", "O", "N"), c("C", "O", "N"))
unique(list1)

And I have obtained the expected result.

Question. How to obtain the result for the list that came from the igraph object?

Edit.

> dput(walks)
list(structure(c(1L, 7L, 2L), .Names = c("C", "O", "D"), env = <weak reference>, graph = "d1edbf24-043a-11ea-aa53-d7a9b9f5ae37", class = "igraph.vs"), 
    structure(c(1L, 7L, 4L), .Names = c("C", "O", "J"), class = "igraph.vs", env = <weak reference>, graph = "d1edbf24-043a-11ea-aa53-d7a9b9f5ae37"), 
    structure(c(1L, 7L, 6L), .Names = c("C", "O", "N"), env = <weak reference>, graph = "d1edbf24-043a-11ea-aa53-d7a9b9f5ae37", class = "igraph.vs"), 
    structure(c(1L, 7L, 6L), .Names = c("C", "O", "N"), env = <weak reference>, graph = "d1edbf24-043a-11ea-aa53-d7a9b9f5ae37", class = "igraph.vs"))

In the short form I see:

> dput(walks, control = NULL)
list(c(1, 7, 2), c(1, 7, 4), c(1, 7, 6), c(1, 7, 6))

Solution

  • The unique function is the right choice, in this case it doesn't work because the elements in your list have a class "igraph". You need to extract the names out first, and apply unique.

    There's some strange "env" in your dput, so I simulated some data below to illustrate it:

    library(igraph)
    set.seed(111)
    g <- make_ring(9, directed = TRUE) %u%
      make_star(10, center = 10) + edge(10, 1)
    g <- set.vertex.attribute(g, "name", value=letters[1:10])
    
    result = lapply(1:5,function(i)random_walk(g, start = 1, steps = 3))
    

    You get something similar to your example:

    > result
    [[1]]
    + 3/10 vertices, named, from 0105e1a:
    [1] a b c
    
    [[2]]
    + 3/10 vertices, named, from 0105e1a:
    [1] a b c
    
    [[3]]
    + 3/10 vertices, named, from 0105e1a:
    [1] a j a
    
    [[4]]
    + 3/10 vertices, named, from 0105e1a:
    [1] a j a
    
    [[5]]
    + 3/10 vertices, named, from 0105e1a:
    [1] a j a
    
    > class(result[[1]])
    [1] "igraph.vs"
    

    You can check the two different outputs:

    # does not work for you
    unique(walks)
    # this works
    unique(lapply(walks,names))
    > unique(lapply(walks,names))
    [[1]]
    [1] "a" "j" "a"
    
    [[2]]
    [1] "a" "b" "c"
    
    [[3]]
    [1] "a" "b" "j"