Search code examples
rdplyrigraphdata-manipulationedge-list

Get edge list that includes alter's alters


I need a data frame that includes three columns: i, j (alter), and k (j's alter). I have an adjacency matrix (sample below). From there I can get a graph object and extract the edge list. How can I manipulate the data to get an output like the WANT data frame below?

HAVE (matrix & edgelist):

      1   2   3   4   5   

 1    0   0   0   1   0  
 2    0   0   1   1   1   
 3    0   0   0   0   0   
 4    1   1   0   0   1   
 5    1   1   0   1   0    


g <- graph_from_adjacency_matrix(mat)

get.edgelist(g)


i   j

1   4
2   3
2   4
2   5
4   1
4   2
4   5
5   1
5   2
5   4

WANT (ijk edge list):

i j k
1 4 2
1 4 5
2 4 1
2 4 5
4 2 3
4 5 1
4 5 2
5 1 4 
5 2 3
5 2 4
5 4 1
5 4 2

the ijk edge list should so all possible triples with ij, excluding self loops(ex: 1 4 1)


Solution

  • Data:

    as.matrix(read.table(text = "0   0   0   1   0  
                                 0   0   1   1   1   
                                 0   0   0   0   0   
                                 1   1   0   0   1   
                                 1   1   0   1   0",
                         header = F, stringsAsFactors = F)) -> m1
    
    dimnames(m1) <- list(1:5, 1:5)
    

    Libraries:

    library(igraph) 
    library(dplyr)
    library(tidyr)
    library(magrittr)
    

    Solution:

    g1 <- graph_from_adjacency_matrix(m1)
    e1 <- get.edgelist(g1) %>% as.data.frame %>% mutate_if(is.factor, as.character)
    
    e1 %>% 
      group_by(V1) %>% 
      nest(V2) %>% 
      right_join(e1,.,by = c("V2"="V1")) %>%  
      unnest %>% 
      filter(V1 != V21) %>% 
      set_colnames(c("i", "j", "k"))
    

    Output:

    #>    i j k
    #> 1  1 4 2
    #> 2  1 4 5
    #> 3  2 4 1
    #> 4  2 4 5
    #> 5  2 5 1
    #> 6  2 5 4
    #> 7  4 2 3
    #> 8  4 2 5
    #> 9  4 5 1
    #> 10 4 5 2
    #> 11 5 1 4
    #> 12 5 2 3
    #> 13 5 2 4
    #> 14 5 4 1
    #> 15 5 4 2