I will not have time to maintain this package anymore. If anyone wants to take over, please let me know.
R package for resampling network metrics/indices (bootstrapping without replacement).
GitHub site at: https://valentinitnelav.github.io/bootstrapnet/index.html
It wraps around the bipartite package functions networklevel
and specieslevel
.
Assuming a network/web like Safariland
from the bipartite package:
library(bipartite)
data(Safariland)
One can sample interactions without replacement from the network until all interactions have been used. The sampling procedure starts with a small sample size to which interactions are added until all are consumed. Every time we sample interactions, a smaller version of the entire network can be built and a network index/metric can be computed. The sampling procedure can be repeated as many times as needed, giving the possibility to compute mean values with quantile-based confidence intervals. The mean values across sample sizes can be plotted and indices of different networks can be visually compared. See examples below.
Below is an animation of the sampling method (one iteration). A detailed explanation of the method can be found here.
You can install bootstrapnet
from GitHub with:
using devtools
package
if (!require(devtools)) install.packages("devtools")
devtools::install_github("valentinitnelav/bootstrapnet")
using remotes
package
if (!require(remotes)) install.packages("remotes")
remotes::install_github("valentinitnelav/bootstrapnet")
If there might be some administrative firewall on your computer and you get some "proxy" error message, then see issue #29 with this possible solution:
if (!require(remotes)) install.packages("remotes")
remotes::install_url("https://github.com/valentinitnelav/bootstrapnet/archive/HEAD.zip")
See more examples here
library(bootstrapnet)
library(bipartite)
library(magrittr)
data(Safariland)
# Generate two fictive networks to compare
set.seed(321)
Safariland_1 <- Safariland[, sort(sample.int(ncol(Safariland), 20))]
set.seed(123)
Safariland_2 <- Safariland[, sort(sample.int(ncol(Safariland), 20))]
# Resample the two networks with computing "nestedness". The computation is
# carried in parallel.
lst_nest <- list(s1 = Safariland_1, s2 = Safariland_2) %>%
lapply(web_matrix_to_df) %>%
boot_networklevel(col_lower = "lower", # column name for plants
col_higher = "higher", # column name for insects
index = "nestedness",
level = "both", # here, nestedness is not affected by level
start = 20,
step = 10,
n_boot = 100,
n_cpu = 3)
# approx. 1 min of CPU time
gg_networklevel(lst_nest)
spl_size
represents the number of interactions sampled (without replacement) from each network/web (here, s1 and s2). The first sample is set to start = 20
interactions. These 20 interactions form a small web for which a nestedness value is computed. Then we add 10 more randomly sampled interactions (step = 10
) that where not sampled yet. The new network has now 30 interactions and a new nestedness is computed for spl_size = 30
, and so on until all interactions were sampled (that is, the entire web).
So, after the first start = 20
sample, at each step of 10 sampled interactions (step = 10
), a metric is computed (here nestedness). The last computed index value (right most tip of a bootstrap mean line) corresponds to the index value of the entire network (because at this point, as mentioned above, the entire network was sampled).
These operations are repeated n_boot = 100
times in parallel on n_cpu = 3
CPUs for each web (s1 & s2). For each web, each thinner line represents one of the 100 iterations. Having 100 nestedness values at each spl_size
, then we can compute an average and the 95% quantile-based confidence intervals (CI) around it. Therefore, we get the mean thicker line and its 95% CI dashed lines. Is normal to see wider 95% CIs at smaller spl_size
since there is high variation in the networks constructed from the few sampled interactions. At the other end, the CIs have to converge at the final index value, which is the index of the entire network (see values below).
The same resampling / bootstrapping procedure is applied for species level indices.
# The last computed index value (right most tip of a bootstrap mean line)
# corresponds to the index value of the entire network:
networklevel(Safariland_1, index = "nestedness")
## nestedness
## 17.36351
networklevel(Safariland_2, index = "nestedness")
## nestedness
## 23.23792
Such accumulation/rarefaction curves allow comparison of networks/webs with different number of interactions. Ideally the indices/metrics will be compared if the curves display a trend of reaching an asymptote. That means that if we keep on investing effort to sample interactions (observe plant-pollinator in the field) we will not gain much further information, so network comparison is already possible.
Here, the web s2, even though has fewer interactions, seems to produce a stable, asymptotic resampled nestedness (blue line) as the one of web s1 (red line). The two networks are not much different in terms of nestedness, since the 95% CI overlap considerably.
You could fork the github repository, apply your changes, test if things work properly and then submit a pull request. Moreover, feel free to check or open issues about code and documentation suggestions, bugs, etc.
I am open to code improvements for speed, readability, better modularity, practical simplifications, etc. Please, always comment as much as possible your code and reasoning. Better comment more than less :)
Releases of the package are constantly archived on Zenodo at this link where you find also their suggestion for citation. Inspired from Zenodo’s suggestion, you could cite as:
Valentin Ștefan, & Tiffany Marie Knight. (2020). R package for bootstrapping indices of ecological networks. Zenodo. http://doi.org/10.5281/zenodo.3997559
Zoller, L., Bennett, J., & Knight, T. M., 2023. Plant–pollinator network change across a century in the subarctic. Nature Ecology & Evolution, 1-11. Link to paper here
Rakosy, D., et al. 2022. Intensive grazing alters the diversity, composition and structure of plant-pollinator interaction networks in Central European grasslands. PloS one, 17(3), e0263576. Link to paper here
Motivans Švara, Elena, et al., 2021. Effects of different types of low‐intensity management on plant‐pollinator interactions in Estonian grasslands. Ecology and evolution 11.23: 16909-16926. Link to paper here
Kelly, T. and Elle, E., 2020. Effects of community composition on plant–pollinator interaction networks across a spatial gradient of oak-savanna habitats. Oecologia, 193(1), pp.211-223.