Skip to content

Commit af0c5aa

Browse files
committed
Major update
Shorter, faster code for combining incidence matrices to make a multilayer network formatted for igrpah.
1 parent 99ac9ac commit af0c5aa

File tree

4 files changed

+59
-92
lines changed

4 files changed

+59
-92
lines changed

figures/net1_igraph_graph.png

-15.6 KB
Loading
-36.9 KB
Loading
24.8 KB
Loading

network-drawing.R

Lines changed: 59 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ rm(list= ls())
4242

4343
# Load the required packages
4444
library(bipartite)
45+
library(dplyr)
4546
library(igraph)
4647
library(reshape2)
4748
library(tidyverse)
@@ -251,19 +252,19 @@ dev.off()
251252
# lists. However, in most cases, ecologists usually have incidence matrices
252253
# to begin the analysis.
253254

254-
# If your data are organized as edge and vertex lists, go to step 6B. Otherwise,
255-
# proceed to step 6A.
255+
# If your data are organized as edge and vertex lists, you life will be much
256+
# easier. See another script focused on multilayer networks:
257+
# https://github.com/marmello77/multilayer-networks
256258

259+
# Otherwise, proceed to the next step in this script. You'll need to transform
260+
# your matrices.
257261

258-
##### 6A: starting with incidence matrices
259-
260-
261-
# We are going to work with a multilayer network composed of two layers:
262+
# OK, we are going to work with a multilayer network composed of two layers:
262263
# one with antagonistic interactions and the other with mutualistic
263264
# interactions. These layers are represented by two matrices with equal
264-
# dimensions and exactly the same label order for the rows and columns.
265+
# dimensions and exactly the same label order for rows and columns.
265266

266-
# Let's take a look at those matrices, which we've already imported. See that
267+
# Let's take a look at the matrices, which we've already imported. See that
267268
# they are like reflections in a mirror, but with different values in their
268269
# cells.
269270

@@ -273,105 +274,71 @@ net3an_bi
273274
# Mutualistic matrix:
274275
net3mu_bi
275276

276-
# Fortunately, we've already converted them into igraph format. Do you remember
277-
# their attributes?
278-
net3an_ig
279-
net3mu_ig
280-
281-
# First, let's create a new attributed with info on interaction types
282-
E(net3an_ig)$layer <- "antagonistic"
283-
E(net3mu_ig)$layer <- "mutualistic"
284-
285-
# Check the layers
286-
E(net3an_ig)$layer
287-
E(net3mu_ig)$layer
288-
289-
# Now let's inform which vertices are animals and plants
290-
V(net3an_ig)$taxon = ifelse(V(net3an_ig)$type == FALSE, "animals", "plants")
291-
V(net3mu_ig)$taxon = ifelse(V(net3mu_ig)$type == FALSE, "animals", "plants")
292-
293-
# Check the taxonomic groups
294-
V(net3an_ig)$taxon
295-
V(net3mu_ig)$taxon
296-
297-
# Now let's export the edge lists (links)
298-
net3an_links <- as.data.frame(as_edgelist(net3an_ig, names = TRUE))
299-
net3mu_links <- as.data.frame(as_edgelist(net3mu_ig, names = TRUE))
300-
301-
# Check the edge lists
302-
net3an_links
303-
net3mu_links
277+
#Transform these matrices into a combined edge list
278+
net3list <- bind_rows(
279+
as.data.frame(as.table(net3an_bi)),
280+
as.data.frame(as.table(net3mu_bi)),
281+
.id = "layer") %>%
282+
283+
filter(Freq != 0) %>%
284+
select(
285+
from = Var1,
286+
to = Var2,
287+
layer,
288+
Freq)
304289

305-
# Add info on the layers
306-
net3an_links$layer <- "antagonistic"
307-
net3mu_links$layer <- "mutualistic"
290+
#Check the data
291+
head(net3list)
308292

309-
# Give the columns informative names
310-
colnames(net3an_links) <- c("animals", "plants", "layer")
311-
colnames(net3mu_links) <- c("animals", "plants", "layer")
293+
#Give the columns informative names
294+
colnames(net3list) <- c("animals", "plants", "layer", "weight")
312295

313-
# Bring back the information on edge weights
314-
net3an_links$weight <- E(net3an_ig)$weight
315-
net3mu_links$weight <- E(net3mu_ig)$weight
296+
#Check the data
297+
head(net3list)
316298

317-
# Now create vertex lists
318-
net3an_nodes <- data.frame(node=character(length(V(net3an_ig)$name)),
319-
taxon=character(length(V(net3an_ig)$taxon)),
320-
stringsAsFactors=FALSE)
321-
net3an_nodes$node <- V(net3an_ig)$name
322-
net3an_nodes$taxon <- V(net3an_ig)$taxon
299+
#Transform the combined edge list into an igraph object
300+
net3_multi <- graph_from_data_frame(net3list, directed = FALSE)
323301

324-
net3mu_nodes <- data.frame(node=character(length(V(net3mu_ig)$name)),
325-
taxon=character(length(V(net3mu_ig)$taxon)),
326-
stringsAsFactors=FALSE)
327-
net3mu_nodes$node <- V(net3mu_ig)$name
328-
net3mu_nodes$taxon <- V(net3mu_ig)$taxon
329-
330-
# Check the vertex lists
331-
net3an_nodes
332-
net3mu_nodes
333-
334-
# Now let's merge the two layers
335-
net3_links = rbind(net3an_links, net3mu_links)
336-
net3_nodes = rbind(net3an_nodes, net3mu_nodes)
337-
net3_nodes = unique(net3_nodes)
338-
339-
340-
##### ATTENTION: #####
341-
# If your data are already organized as vertex and edge lists, you can begin
342-
# right here, instead of having to go through all previous steps
343-
######################
344-
345-
346-
##### 6B: starting with edge and vertex lists
347-
348-
349-
# Create a new multilayer network formatted for igraph
350-
net3_multi <- graph_from_data_frame(d=net3_links, vertices=net3_nodes, directed=F)
351-
class(net3_multi)
302+
#Check the multilayer network
352303
net3_multi
304+
V(net3_multi)
305+
E(net3_multi)
306+
attributes(V(net3_multi))
307+
attributes(E(net3_multi))
308+
V(net3_multi)$type
309+
V(net3_multi)$name
310+
E(net3_multi)$layer
311+
E(net3_multi)$weight
312+
313+
# Create a new edge attribute with info on interaction types (layers)
314+
E(net3_multi)$layer <- ifelse(E(net3_multi)$layer == "1",
315+
"antagonistic",
316+
"mutualistic")
353317

354-
# Add information on the bipartite structure
355-
V(net3_multi)$type <- ifelse(V(net3_multi)$taxon == "animals", "animals", "plants")
318+
# Check the layers
319+
E(net3_multi)$layer
356320

357-
# Check the network's attributes again to check if it's undirected, named,
358-
# weighted, and bipartite. Check also its number of vertices and edges
321+
# Add information on the bipartite structure by asggining vertex classes
322+
V(net3_multi)$type = c(rep(0, nrow(net3an_bi)),
323+
rep(1, ncol(net3an_bi)))
324+
325+
# Check the network's attributes and the vertex classes
359326
net3_multi
327+
V(net3_multi)$type
360328

361-
# As net2, this network does also contain 3 taxonomic groups: marsupials,
362-
# rodents, and plants. So let's recover this information now.
329+
# As net2, this network does also contain 3 taxonomic groups. In this case,
330+
# marsupials, rodents, and plants. So let's recover this information now.
363331
# Create a new vertex attribute with the taxonomic groups
364-
V(net3_multi)$taxon2 = c(c("Rodents", "Rodents", "Marsupials", "Marsupials",
365-
"Marsupials", "Rodents", "Rodents", "Marsupials",
366-
"Rodents"),
367-
rep("Plants", ncol(net3an_bi))
368-
)
332+
V(net3_multi)$taxon = c(c("Rodents", "Rodents", "Marsupials", "Marsupials",
333+
"Marsupials", "Rodents", "Rodents", "Marsupials",
334+
"Rodents"),
335+
rep("Plants", ncol(net3an_bi)))
369336

370337
# Check the taxonomic groups
371-
V(net3_multi)$taxon2
338+
V(net3_multi)$taxon
372339

373340
# Set vertex colors by taxonomic group
374-
V(net3_multi)$color = V(net3_multi)$taxon2
341+
V(net3_multi)$color = V(net3_multi)$taxon
375342
V(net3_multi)$color = gsub("Marsupials","gold",V(net3_multi)$color)
376343
V(net3_multi)$color = gsub("Rodents","purple",V(net3_multi)$color)
377344
V(net3_multi)$color = gsub("Plants","darkgreen",V(net3_multi)$color)

0 commit comments

Comments
 (0)