library(emln)
library(igraph)
library(tidyverse)
library(bipartite)
library(magrittr)
We provide examples with simulated toy networks and with real data to
create an object of class monolayer
. See help
(?monolayer
) to learn more about this class
We start with a toy example. We generate a 3x3 matrix with random weighted interactions.
n <- 3
adjacency_matrix <- matrix(round(runif(n*n,1,5),0), ncol = n, dimnames = list(paste0("A", 1:n), paste0("A", 1:n)))
# Convert a matrix to a monolayer object
matrix_to_list_unipartite(adjacency_matrix, directed = TRUE)
## $mode
## [1] "U"
##
## $directed
## [1] TRUE
##
## $nodes
## # A tibble: 3 × 2
## node_id node_name
## <int> <chr>
## 1 1 A1
## 2 2 A2
## 3 3 A3
##
## $mat
## A1 A2 A3
## A1 2 2 3
## A2 4 2 4
## A3 3 2 2
##
## $edge_list
## # A tibble: 9 × 3
## from to weight
## <chr> <chr> <dbl>
## 1 A1 A1 2
## 2 A1 A2 4
## 3 A1 A3 3
## 4 A2 A1 2
## 5 A2 A2 2
## 6 A2 A3 2
## 7 A3 A1 3
## 8 A3 A2 4
## 9 A3 A3 2
##
## $igraph_object
## IGRAPH 2382cdb DNW- 3 9 --
## + attr: name (v/c), weight (e/n)
## + edges from 2382cdb (vertex names):
## [1] A1->A1 A1->A2 A1->A3 A2->A1 A2->A2 A2->A3 A3->A1 A3->A2 A3->A3
##
## attr(,"class")
## [1] "monolayer"
Now let’s see a toy example for converting a link list.
# Generate a data frame with random links
link_list_unipartite <- data.frame(from=c("A1", "A1", "A1", "A2", "A2", "A2", "A3", "A3","A3"), to=c("A1", "A2", "A3", "A1", "A2", "A3", "A1", "A2","A3"), weight=round(runif(n*n,1,5),0))
list_to_matrix(link_list_unipartite, directed = TRUE, bipartite = FALSE)
## $mode
## [1] "U"
##
## $directed
## [1] TRUE
##
## $nodes
## # A tibble: 3 × 2
## node_id node_name
## <int> <chr>
## 1 1 A1
## 2 2 A2
## 3 3 A3
##
## $mat
## A1 A2 A3
## A1 3 4 4
## A2 4 4 2
## A3 1 4 1
##
## $edge_list
## from to weight
## 1 A1 A1 3
## 2 A1 A2 4
## 3 A1 A3 1
## 4 A2 A1 4
## 5 A2 A2 4
## 6 A2 A3 4
## 7 A3 A1 4
## 8 A3 A2 2
## 9 A3 A3 1
##
## $igraph_object
## IGRAPH 3000e18 DNW- 3 9 --
## + attr: name (v/c), weight (e/n)
## + edges from 3000e18 (vertex names):
## [1] A1->A1 A1->A2 A1->A3 A2->A1 A2->A2 A2->A3 A3->A1 A3->A2 A3->A3
##
## attr(,"class")
## [1] "monolayer"
To illustrate working with real data we will use a binary directed marine food web from Jacob, Ute, Aaron Thierry, Ulrich Brose, Wolf E. Arntz, Sofia Berg, Thomas Brey, Ingo Fetzer, et al. 2011. “The Role of Body Size in Complex Food Webs: A Cold Case.” In Advances in Ecological Research, edited by Andrea Belgrano, 45:181–223. Academic Press. Kongsfjorden is a glacial fjord on the northwest corner of the Svalbard archipelago. It is a 30 km open fjord with no marked sill at the entrance, and with a maximum depth exceeding 300 m. The network consists of 262 species with 1,544 feeding interactions. Note the warning messages; these are OK for this data set.
These data are organized as a link list, so it is possible to include node attributes.
# The data is included in the infomapecology package
data("kongsfjorden_links", package = 'infomapecology')
data("kongsfjorden_nodes", package = 'infomapecology')
nodes <- kongsfjorden_nodes %>%
select(node_name=Species, node_id_original=NodeID, everything())
interactions <- kongsfjorden_links %>%
select(from=consumer, to=resource) %>%
mutate_if(is.factor, as.character) %>%
mutate(weight=1)
monolayer_unipartite <- list_to_matrix(x=interactions, directed = T, bipartite = F, node_metadata = nodes)
head(monolayer_unipartite$nodes)
## # A tibble: 6 × 2
## node_id node_name
## <int> <chr>
## 1 1 Phaeocystis pouchetii
## 2 2 Chaetoceros socialis
## 3 3 Thalassiosira nordenskioeldii
## 4 4 Fragilariopsis
## 5 5 Protoperidinium
## 6 6 Gymnodinium
head(monolayer_unipartite$edge_list)
## from to weight
## 1 Calanus finnmarchicus Phaeocystis pouchetii 1
## 2 Calanus finnmarchicus Chaetoceros socialis 1
## 3 Calanus finnmarchicus Thalassiosira nordenskioeldii 1
## 4 Calanus finnmarchicus Fragilariopsis 1
## 5 Calanus finnmarchicus Protoperidinium 1
## 6 Calanus finnmarchicus Gymnodinium 1
Now let’s take the matrix we obtained as an example, and create a monolayer object from a matrix.
kongsfjorden_matrix <- monolayer_unipartite$mat
monolayer_unipartite <- matrix_to_list_unipartite(x = kongsfjorden_matrix, directed = T)
## [1] "Some nodes have no interactions. They will appear in the node table but not in the edge list"
We start with a toy example. We generate a random incidence matrix with dimensions P X A. Bipartite networks have two sets of nodes with no overlap between the sets.
# Case "Bipartite networks"
#
P <- 4 # 4 rows
A <- 3 # 3 columns
incidence_matrix <- matrix(round(runif(P*A,1,5),0), ncol = A, dimnames = list(paste0("P", 1:P), paste0("A", 1:A)))
# Convert an matrix to an edge list for bipartite network
matrix_to_list_bipartite(incidence_matrix, group_names = c('A_set', 'P_set'))$edge_list
## # A tibble: 12 × 3
## from to weight
## <chr> <chr> <dbl>
## 1 A1 P1 4
## 2 A1 P2 1
## 3 A1 P3 5
## 4 A1 P4 3
## 5 A2 P1 5
## 6 A2 P2 4
## 7 A2 P3 5
## 8 A2 P4 4
## 9 A3 P1 1
## 10 A3 P2 2
## 11 A3 P3 3
## 12 A3 P4 1
To demonstrate real data we use the incidence matrix olesen2002flores included in the bipartite package.
# create a monolayer object from a bipartite matrix
monolayer_bipartite <- matrix_to_list_bipartite(x = olesen2002flores, group_names = c('Pollinator', 'Plant'))
# What is included in the monolayer class object
names(monolayer_bipartite)
## [1] "mode" "directed" "nodes" "mat" "edge_list" "igraph_object"
# The nodes in the network
monolayer_bipartite$nodes
## # A tibble: 22 × 3
## node_id node_group node_name
## <int> <chr> <chr>
## 1 1 Pollinator Halictus.sp.
## 2 2 Pollinator Sepsis.thoracica
## 3 3 Pollinator Agrotis.ipsilon
## 4 4 Pollinator Bombus.ruderatus
## 5 5 Pollinator Colias.crocea
## 6 6 Pollinator Musca.domestica
## 7 7 Pollinator Apis.mellifera
## 8 8 Pollinator Lucilia.sericata
## 9 9 Pollinator Lasius.niger
## 10 10 Pollinator Anothomyia.pluvialis
## # ℹ 12 more rows
# The link (edge) list
monolayer_bipartite$edge_list
## # A tibble: 30 × 3
## from to weight
## <chr> <chr> <dbl>
## 1 Halictus.sp. Azorina:vidalii 98
## 2 Halictus.sp. Solidago:sempervivens 141
## 3 Halictus.sp. Daucus:carota 11
## 4 Halictus.sp. Silene:vulgaris 7
## 5 Halictus.sp. Chamomilla:suaveolens 21
## 6 Halictus.sp. Reseda:luteola 11
## 7 Sepsis.thoracica Azorina:vidalii 51
## 8 Sepsis.thoracica Crithmum:maritimum 87
## 9 Sepsis.thoracica Beta:vulgaris 8
## 10 Sepsis.thoracica Silene:vulgaris 30
## # ℹ 20 more rows
# An igraph object is also created
monolayer_bipartite$igraph_object
## IGRAPH 972da5b UNWB 22 30 --
## + attr: type (v/l), name (v/c), weight (e/n)
## + edges from 972da5b (vertex names):
## [1] Halictus.sp. --Azorina:vidalii Halictus.sp. --Solidago:sempervivens Halictus.sp. --Daucus:carota
## [4] Halictus.sp. --Silene:vulgaris Halictus.sp. --Chamomilla:suaveolens Halictus.sp. --Reseda:luteola
## [7] Sepsis.thoracica--Azorina:vidalii Sepsis.thoracica--Crithmum:maritimum Sepsis.thoracica--Beta:vulgaris
## [10] Sepsis.thoracica--Silene:vulgaris Agrotis.ipsilon --Solidago:sempervivens Bombus.ruderatus--Azorina:vidalii
## [13] Bombus.ruderatus--Lotus:corniculatus Bombus.ruderatus--Freesia:refracta Colias.crocea --Azorina:vidalii
## [16] Colias.crocea --Lotus:corniculatus Colias.crocea --Freesia:refracta Musca.domestica --Azorina:vidalii
## [19] Musca.domestica --Crithmum:maritimum Musca.domestica --Daucus:carota Musca.domestica --Chamomilla:suaveolens
## [22] Apis.mellifera --Azorina:vidalii Apis.mellifera --Lotus:corniculatus Apis.mellifera --Reseda:luteola
## + ... omitted several edges
We can also convert a link list to a monolayer object.
ll <- monolayer_bipartite$edge_list
monolayer_bipartite_2 <- list_to_matrix(ll, bipartite = T, group_names = c('Pollinator', 'Plant'))
create_monolayer_network
This function is a wrapper for the
matrix_to_list_unipartite
,
matrix_to_list_bipartite
, and list_to_matrix
functions. It is convenient because it automatically selects the input
type.
#Input is a link list
monolayer_unipartite <- create_monolayer_network(x=interactions, directed = T, bipartite = F, node_metadata = nodes)
## [1] "Input: an unipartite edge list"
# Input is a matrix
bipartite_monolayer <- create_monolayer_network(x = olesen2002flores, group_names = c('Pollinator', 'Plant'), bipartite = T)
## [1] "Input: a bipartite matrix"