Chapter 3 Sampling an ecological network
Eva Knop and Vincent Grognuz
session 18/03/2025
Field work
For this exercise session, you will go outside to collect data on species interactions in order to build your own pollination network. You can find instructions on how to collect interaction data in the slides provided. Moreover (weather permitting), we will demonstrate what you should do at the Irchel Park.
An important thing to keep in mind is that you should record the interactions you sample in the file we provide. You can download the file here. This is the file you are expected to use when building your network in R.
Data analysis and report preparation
After having collected your data, you should do the following tasks:
- Load the data you collected in the field into R
- Convert the data into a network
- Visualize your network
We expect you to submit a short report that combines your code, data,
and visualisations. To do so, we provide you with a template Rmarkdown
file that you can fill in. You can find this file here:
/workspace/03-18_sampling_an_ecological_network
.
Please keep in mind that the deadline to submit the report for this exercise session is Saturday, April 5th at 1:00 pm. If you have questions, please do not hesitate to contact us.
3.1 Practical demonstration
To walk you through all the steps needed to prepare your report we will work with a mock data set.
Load data
After you recorded your data into the file called
species_interactions_protocol.csv
, you will need to upload it to the
Rstudio Server. To do so, you can click on the Upload button found on
the bottom right panel of Rstudio. This will allow you to navigate your
file system to find the file you wish to upload and then upload it
directly to the server. Once the file is on the server, we can load the
relevant packages we will need and read the data into R as follows:
# Load packages
library(igraph)
library(dplyr)
library(bipartite)
# Read data into R
data <- read.csv("~/ecological_networks_2025/downloads/Data/sampling_an_ecological_network/species_interactions_protocol_example.csv")
Note that you will need to change the file path so that it points to the location where your data is stored on the server(!).
Next we can check that the data was imported correctly:
## plant insect date time temperature
## 1 Primula.vulgaris Bombus.terrestris 22.03.22 14:02 18
## 2 Primula.vulgaris Bombus.terrestris 22.03.22 14:02 18
## 3 Primula.vulgaris Episyrphus.balteatus 22.03.22 14:02 18
## 4 Primula.vulgaris Hymenoptera.sp2 22.03.22 14:15 18
## 5 Salix.sp Bombus.m1 23.03.22 14:05 18
## 6 Salix.sp Bombus.m1 23.03.22 14:05 18
3.1.1 Convert data to a bipartite network
Now that you have loaded your data set, you need to convert it into an
igraph
object, i.e., “something” that is suitable to be visualized and
to be analyzed quantitatively as a network. Let’s start by converting
our raw data into an edge list:
# convert the raw data into an edge list
my_edge_list <- data |>
# only select relevant columns
select(plant, insect) |>
# group by each unique combination of plant and insect
group_by(plant, insect) |>
# summarise the groups by adding a new column which counts the number of
# interactions between each unique combination of plant and insect
summarise(connection_strength = n()) |>
# ungroup the plants and animals
ungroup()
Now our data is formatted in such a way that each row summarises the number of interactions between a pair of plant and insect:
## # A tibble: 6 × 3
## plant insect connection_strength
## <chr> <chr> <int>
## 1 "Gallanthus.nivalis" "Apis.mellifera" 1
## 2 "Primula.vulgaris " "Bombus.terrestris" 2
## 3 "Primula.vulgaris " "Episyrphus.balteatus" 1
## 4 "Primula.vulgaris " "Hymenoptera.sp1" 1
## 5 "Primula.vulgaris " "Hymenoptera.sp2" 3
## 6 "Salix.sp " "Bombus.m1 " 4
Following the procedure we have applied in the session
toolkit for network analysis
, we can convert our edge list into a
network using the igraph
package.
# Convert the edge list into network
my_network <- graph_from_data_frame(my_edge_list, directed = FALSE)
# Check network
my_network
## IGRAPH 2780125 UN-- 11 9 --
## + attr: name (v/c), connection_strength (e/n)
## + edges from 2780125 (vertex names):
## [1] Gallanthus.nivalis --Apis.mellifera
## [2] Primula.vulgaris --Bombus.terrestris
## [3] Primula.vulgaris --Episyrphus.balteatus
## [4] Primula.vulgaris --Hymenoptera.sp1
## [5] Primula.vulgaris --Hymenoptera.sp2
## [6] Salix.sp --Bombus.m1
## [7] Salix.sp --Episyrphus.balteatus
## [8] Taraxacum.officinalis--Episyrphus.balteatus
## + ... omitted several edges
Now we need to make our network bipartite. To do so, we can use the
bipartite_mapping
function to automatically assign plants and insects
to separate groups:
# Assign groups to insects and plants
bipartite_mapping_output <- bipartite_mapping(my_network)
# Set these groups to the nodes of the network
V(my_network)$type <- bipartite_mapping_output$type
# Confirm that network is now bipartite
is_bipartite(my_network)
## [1] TRUE
3.1.2 Plot the network
We can plot the network using either the igraph
or bipartite
package. Remember, however, that each one requires our network to be
represented in different formats. igraph
requires a network object
while bipartite
requires an incidence matrix.
Let’s first plot our network using igraph
:
# Set the layout for our plot
LO = layout_as_bipartite(my_network)
# Visualize our network
plot(my_network, # define the network we want to plot
vertex.label=V(my_network)$Name, # define the node labels
vertex.size=8, # define node size
vertex.label.dist=9, # define position of node labels
layout=LO[,2:1], # tweak layout
vertex.label.degree = pi*V(my_network)$type, # tweak position of labels
vertex.label.cex=0.8, # define label size
vertex.color = rgb(0.8,0.4,0.3,0.8), # define colour of nodes
vertex.label.family="Times", # define typography
vertex.label.color="black", # define colour of border
edge.color="black", # define colour of links
main = "My Network") # define title
If we want to plot our network using the bipartite
package, we first
need to convert our network into an incidence matrix:
# Convert the igraph object into incidence matrix
my_incidence_matrix <- as_incidence_matrix(
my_network,
attr = "connection_strength",
names = TRUE,
sparse = FALSE
)
# Check matrix
my_incidence_matrix
## Apis.mellifera Bombus.terrestris Episyrphus.balteatus
## Gallanthus.nivalis 1 0 0
## Primula.vulgaris 0 2 1
## Salix.sp 0 0 1
## Taraxacum.officinalis 0 0 1
## Yellow.flower .m1 0 0 0
## Hymenoptera.sp1 Hymenoptera.sp2 Bombus.m1
## Gallanthus.nivalis 0 0 0
## Primula.vulgaris 1 3 0
## Salix.sp 0 0 4
## Taraxacum.officinalis 0 0 0
## Yellow.flower .m1 0 0 1
Now we can plot our network:
# Plot the network
# (you can tweak the arguments to change the look of your network)
plotweb(my_incidence_matrix, # define the matrix
text.rot=90, # rotate the text
bor.col.interaction="gray40", # define colour of links
col.high="blue", # define colour of top level
col.low="darkgreen", # define colour of lower level
y.lim=c(-1,3)) # tweak y axis so that network is visible in RMARKDOWN
3.2 Your task
We expect you to repeat the analysis shown above with the data set you
collected during the block course. We ask you to upload the raw data you
collected as a .csv
file onto the server filling the template provided
by us.
Please store your data set in the folder
workspace/03-18_sampling_an_ecological_network/
. Later you can use the
03-18_sampling_an_ecological_network.Rmd
script therein to produce
your report in html format. Once you are done, please download the whole
folder and upload it on OLAT.
If you encounter technical troubles, please ask Fernando to help you.