rmatrixigraphsocial-networkingvisnetwork

R - Group social network analysis, adding weights to edges


I am trying to create a simple social network of species and their interactions with other species. I have cleaned and coded all my data to have 3 columns (from, to, weight) with the first column being the observed species, second column being the associating species, and weight being how many times that event was observed. I cannot for the life of me figure out how to get the edges to visually represent the weight column. I've tried both igraph and visNetwork (see below).

There are some beautiful answers in How to add specific weights to some edges?, Plot Network Graph and add edge weights to network edges python, Add weight to edge in Network, and plotting graph with igraph in R: edge length proportional to weight, but alas, they are all in Python. Any advice is greatly appreciated!

dput data -

data <- structure(list(from = c(5L, 5L, 5L, 1L, 1L, 1L, 1L, 4L, 4L, 4L, 
2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L), to = c(1L, 2L, 3L, 5L, 4L, 2L, 
3L, 1L, 2L, 3L, 5L, 1L, 4L, 3L, 5L, 1L, 4L, 2L), weight = c(8, 
20, 9, 8, 10, 416, 121, 9, 26, 21, 19, 430, 28, 210, 7, 111, 
20, 203)), row.names = c(NA, -18L), class = "data.frame")

Output -

from     to       weight
<int>    <int>    <dbl>
5        1       8      
5        2       20     
5        3       9      
1        5       8      
1        4       10     
1        2       416        
1        3       121        
4        1       9      
4        2       26     
4        3       21     
2        5       19     
2        1       430        
2        4       28     
2        3       210        
3        5       7      
3        1       111        
3        4       20     
3        2       203    

I used new nodes and edge list to make graph in igraph - required detaching some package info to ensure correct package was being used.

library(igraph)
library("igraph", quietly = TRUE, warn.conflicts = FALSE, verbose = FALSE)

igraphroutes <- graph_from_data_frame(d = data, vertices = nodes, directed = F)
igraphroutes
plot(igraphroutes)

df_edges <- as_data_frame(igraphroutes, what = "edges")
df_edges <- df_edges[order(df_edges$weight),]
new_graph <- graph_from_data_frame(d = df_edges, vertices = as_data_frame(igraphroutes, what = "vertices"))

E(new_graph)$weight

plot(new_graph)

I also tried working within visNetwork

require(visNetwork, quietly = TRUE)
library(visNetwork)
data <- as.data.frame(data) %>%
  mutate(weight = as.numeric(data$weight))

plot(igraphroutes, edge.width=E(igraphroutes)$weight)

visNetwork(nodes, data) %>%
  visEdges(nodes, data) %>%
  visIgraphLayout(layout = "layout_with_fr") -> visual
visual

Solution

  • You can use the weight attribute for edge widths when plotting, e.g.,

    graph_from_data_frame(data) %>%
        plot(edge.width = 5 * E(.)$weight / max(E(.)$weight))
    

    enter image description here