Search code examples
rggraph

Convert tidy dataframe to adjacency matrix


I have a dataframe of paper IDs and author names like so:

library(tidyverse)

df <- tribble(
  ~id, ~name,
  1, "a", 
  1, "b", 
  2, "b", 
  2, "c",
  3, "b",
  3, "c"
)

The interpretation is that authors a and b wrote paper 1 together, while authors b and c wrote papers 2 and 3 together.

I would like to plot this using e.g. ggraph like so:

a - b = c

That is, I would like to to have authors as nodes and number of papers co-authored as edge weights.


Solution

  • You can define the adjacency matrix with base R. Try this:

    # create a 2-mode sociomatrix
    mat <-  t(table(df))
    # create adjacency matrix as product of the 2-mode sociomatrix
    adj.mat <- mat %*% t(mat)
    # if you want the diagonal to be 0 use : diag(adj.mat) <- 0. This can also be done directly
    # with igraph
    # define your network
    library(igraph)
    net <- graph_from_adjacency_matrix(adj.mat, mode = "undirected", weighted = TRUE,
                                       diag = FALSE)
    V(net)$name # vertices (nodes) name
    E(net) # edges
    E(net)$weight # edges weight
    # example of plot
    library(ggraph)
    ggraph(net, layout = "igraph", algorithm = "kk") +
            geom_edge_link(aes(width = weight)) +
            geom_node_point(size = 8, colour = "steelblue") + 
            geom_node_text(aes(label = name)) +
            ggforce::theme_no_axes()
    # output
    

    enter image description here