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
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))