Search code examples
rigraphadjacency-matrixedge-list

Adjacency Matrix from a dataframe


I am trying to convert an edgelist to an adjacent matrix.

Below is the sample data

#Sample Data
User<-c("1","1","2","3","4")  
v1 <- c("b", "b", "a", "d", "c")
v2 <- c("c", "d", "c", "a", "a")
v3 <- c(0, 0, "d", 0, "b")
v4 <- c(0, 0, 0, 0, 0)
v5 <- c(0, 0, 0, 0, 0)

my_data<-data.frame(User, v1, v2, v3, v4, v5)
my_data

If you run this code you will get the below as output,

  User v1 v2 v3 v4 v5
    1  b  c  0  0  0
    1  b  d  0  0  0
    2  a  c  d  0  0
    3  d  a  0  0  0
    4  c  a  b  0  0

Using the data, I want to create an adjacent matrix that looks like follows:

   a  b  c  d
a  0  0  2  2        
b  0  0  1  1
c  2  1  0  1  
d  2  1  1  0 

Basically, the desired output diplays the count how many times each pair appeared in column v1~v5 in the sample data frame.

I have tried to use AdjacencyFromEdgelist function from dils library, also tried to create a matrix shell with NAs and fill out the matrix by looping through the dataframe.

However, I could not get neither way to work.


Solution

  • I think this may be close to what you have in mind. In the rows where there are more than 2 vertices, I considered every existing pairs:

    library(igraph)
    
    do.call(rbind, my_data[-1] |>
              apply(1, \(x) x[x != 0]) |>
              lapply(\(x) t(combn(x, m = 2)))) |>
      graph_from_edgelist(directed = FALSE) %>%
      as_adjacency_matrix()
    
    4 x 4 sparse Matrix of class "dgCMatrix"
      b c d a
    b . 2 1 1
    c 2 . 1 2
    d 1 1 . 2
    a 1 2 2 .
    

    Or without the pip operator in base R:

    tmp <- apply(my_data[-1], 1, function(x) x[x != 0])
    tmp <- do.call(rbind, lapply(tmp, function(x) t(combn(x, m = 2))))
    
    my_graph <- graph_from_edgelist(tmp, directed = FALSE)
    adj_mat <- as_adjacency_matrix(my_graph)
    adj_mat