mobr
The package mobr
is currently available on GitHub and
you can freely download the source code here mobr on GitHub
The easiest option is to install the package directly from GitHub
using the package devtools
. If you do not already have
devtools
installed then need to install it.
If you receive an error we would love to receive your bug report here
mobr
To work with mobr
you need two matrix-like data
tables:
Species abundance data in a community matrix (rows are sites and columns are species)
A site attributes table (rows are sites and columns are site attributes)
The community matrix must include the number of individuals of each species.
The table with the plot attributes should include spatial coordinates
of plots and information on experimental treatments and/or environmental
variables. By default spatial coordinates are assumed to be named “x”
and “y” for the easting and northing respectively unless otherwise
specified by the argument coord_names
. If the supplied
coordinates are latitudes and longitudes be sure to set the argument
latlong = TRUE
which turns on great circle distances rather
than Euclidean distances when computing the spatial, sample-based
rarefaction (sSBR). If temporal trends are of interest rather than
simply only supply one coordinate which represents time.
We will examine a case study on the effects of an invasive plant Lonicera maackii on understory plant biodiversity in a Missouri woodland (Powell et al. 2003). This data was reanalyzed in McGlinn et al. (2018).
This data set is included in mobr
and available after
loading the library
library(mobr)
library(dplyr)
library(ggplot2)
data(inv_comm) # Community matrix
data(inv_plot_attr) # Plot attributes data.frame
## num [1:100, 1:111] 0 0 0 0 0 0 0 0 0 0 ...
## - attr(*, "dimnames")=List of 2
## ..$ : NULL
## ..$ : chr [1:111] "sp1" "sp2" "sp3" "sp4" ...
## group x y
## 1 uninvaded 1 0
## 2 uninvaded 2 0
## 3 uninvaded 3 0
## 4 uninvaded 4 0
## 5 uninvaded 5 0
## 6 uninvaded 6 0
The plot attributes include the information if a plot is located in invaded or uninvaded sites as well as the spatial xy coordinates of a plot.
In order to analyze the data with mobr
the two data
tables have to be combined into on single object
## Only the first 6 rows of any matrices are printed
##
## $tests
## $N
## [1] TRUE
##
## $SAD
## [1] TRUE
##
## $agg
## [1] TRUE
##
##
## $comm (Only first 5 species columns are printed)
## sp1 sp2 sp3 sp4 sp5
## 1 0 0 1 0 0
## 2 0 0 1 0 0
## 3 0 0 6 0 0
## 4 0 1 2 0 0
## 5 0 0 0 0 0
## 6 0 0 0 0 0
##
## $env
## group
## 1 uninvaded
## 2 uninvaded
## 3 uninvaded
## 4 uninvaded
## 5 uninvaded
## 6 uninvaded
##
## $spat
## x y
## 1 1 0
## 2 2 0
## 3 3 0
## 4 4 0
## 5 5 0
## 6 6 0
##
## $latlong
## [1] FALSE
The package mobr
offers functions for exploratory data
analysis and visualization.
First let’s look at the spatial, sample-based rarefaction (sSBR) in which samples are added depending on their spatial proximity.
## Warning in plot_rarefaction(inv_mob_in, "group", ref_level = "uninvaded", :
## Sample based rarefaction methods do not make sense at alpha scale, dropping
## alpha scale curves
We can see that invasion decreases richness and that the magnitude of the effect depends on scale. Let’s dig in further to see if we can better understand exactly what components of the community are changing due to invasion.
First we look at the individual rarefaction curves for each treatment which only reflect the shape of the SAD (i.e., no individual density or aggregation effects):
oldpar <- par(no.readonly = TRUE)
par(mfrow = c(1, 2))
plot_rarefaction(inv_mob_in, 'group', 'uninvaded', 'IBR',
leg_loc = 'bottomright')
Visually you can see there are some big differences in total numbers individuals (i.e., how far on the x-axis the curves go). We can also see that for small numbers of individuals the invaded sites are actually more diverse! This is a bit surprising and it implies that the invaded sites have greater evenness. We can directly examine the species abundance distribution (SAD):
oldpar <- par(no.readonly = TRUE)
par(mfrow = c(1, 2))
plot_abu(inv_mob_in, 'group', type = 'rad', scale = 'alpha', log = 'x')
plot_abu(inv_mob_in, 'group', type = 'rad', scale = 'gamma' , log = 'x')
The SADs suggest that the invaded site has greater evenness in its common species (i.e., flatter left hand-side of rank curve).
There are a myriad of biodiversity indices. We have attempted to chose a subset of metrics that can all be derived from the individual rarefaction curve which capture the aspects of biodiversity we are most interested in, namely:
The metrics we have selected are:
Each of these metrics can be computed for either the sample or group scale individual rarefaction curves as shown in the figure below:
The ratio of a given biodiversity metric at the group and sample scales (i.e., \(\beta_S = S_{group} / S_{sample}\) can provide simple measures of species turnover or \(\beta\)-diversity. Depending on which metric the \(\beta\)-diversity is derived from will determine what aspects of species turnover it is most sensitive too (McGlinn et al. 2018, Chase et al. 2018).
For the invasion dataset we will examine all of the metrics except for coverage based richness (S_C) because some of the samples in this dataset are empty which makes that calculation difficult for this example (see below for examples in which S_C is computed).
indices <- c('N', 'S', 'S_n', 'S_PIE')
inv_div <- tibble(inv_comm) %>%
group_by(group = inv_plot_attr$group) %>%
group_modify(~ calc_comm_div(.x, index = indices, effort = 5,
extrapolate = TRUE))
## Warning in calc_PIE(x, replace = replace): NA was returned because the sample
## contains one or zero individuals.
## Warning in calc_SPIE(x, replace = replace): NA was returned because PIE = 1.
## This happens in samples where all species are singletons.
## Warning in calc_PIE(x, replace = replace): NA was returned because the sample
## contains one or zero individuals.
## Warning in calc_SPIE(x, replace = replace): NA was returned because PIE = 1.
## This happens in samples where all species are singletons.
## Warning in calc_SPIE(x, replace = replace): NA was returned because PIE = 1.
## This happens in samples where all species are singletons.
## Warning in calc_SPIE(x, replace = replace): NA was returned because PIE = 1.
## This happens in samples where all species are singletons.
## Warning in calc_SPIE(x, replace = replace): NA was returned because PIE = 1.
## This happens in samples where all species are singletons.
We can examine the inv_div
object
## # A tibble: 6 × 7
## # Groups: group [1]
## group scale index sample_size effort gamma_coverage value
## <fct> <chr> <chr> <dbl> <dbl> <lgl> <dbl>
## 1 invaded alpha N 1 NA NA 1
## 2 invaded alpha N 1 NA NA 2
## 3 invaded alpha N 1 NA NA 4
## 4 invaded alpha N 1 NA NA 9
## 5 invaded alpha N 1 NA NA 12
## 6 invaded alpha N 1 NA NA 15
There are also functions for plotting the indices at the sample and group levels. First let’s examine species richness:
Invasion appears to decrease local sample diversity but not gamma diversity. Somewhat surprisingly it appears to increase \(\beta\)diversity.
It is possible to compute beta diversity directly rather than using
the calc_comm_div
function by using the
calc_beta_div
function. Here is a quick demonstration. We
can calculate the beta diversity for raw richness (S
),
rarefied richness at 5 individuals (S_n
), and the richness
transformed version of the probability of interspecific encounter
(S_PIE
).
## Warning in calc_PIE(x, replace = replace): NA was returned because the sample
## contains one or zero individuals.
## Warning in calc_SPIE(x, replace = replace): NA was returned because PIE = 1.
## This happens in samples where all species are singletons.
## Warning in calc_PIE(x, replace = replace): NA was returned because the sample
## contains one or zero individuals.
## Warning in calc_SPIE(x, replace = replace): NA was returned because PIE = 1.
## This happens in samples where all species are singletons.
## Warning in calc_SPIE(x, replace = replace): NA was returned because PIE = 1.
## This happens in samples where all species are singletons.
## Warning in calc_SPIE(x, replace = replace): NA was returned because PIE = 1.
## This happens in samples where all species are singletons.
## Warning in calc_SPIE(x, replace = replace): NA was returned because PIE = 1.
## This happens in samples where all species are singletons.
## scale index sample_size effort gamma_coverage value
## 1 beta beta_S 100 NA NA 14.7214854
## 2 beta beta_S_n 100 5 NA 1.0335667
## 3 beta beta_S_PIE 100 NA NA 0.6369648
One of the major effects we observed in the individual rarefaction curve was that the invaded sites appeared to have fewer individuals, let’s examine the test of that:
Clearly our intuition was correct there is a very strong negative
effect of invasion on N. So it appears that the changes we observed in S
may be due to the negative effect of invasion on N. Let’s examine
S_n
to test this:
We can also plot f_0
but for this dataset this metric
does not show strong patterns so we’ll stop here for now. If you want to
plot all the biodiversity metrics at once you can simply use:
The continuous scale analysis using mobr
aims at
disentangling the consequences of three biodiversity components on
observed changes in species richness
To accomplish this we use three different rarefaction curves which each capture different aspects of community structure:
If we examine the difference between each of these curves in our two treatments we can learn how the treatment influences richness via its effects on different components of community structure.
We can carry out this analysis in mobr
using the
function get_delta_stats
. For the sake of speed we’ll run
the analysis with just 20 permutations but at least 200 are recommended
for actual applications.
inv_mob_in <- make_mob_in(inv_comm, inv_plot_attr,
coord_names = c('x', 'y'))
inv_deltaS <- get_delta_stats(inv_mob_in, 'group', ref_level='uninvaded',
type='discrete', log_scale=TRUE, n_perm = 199)
The best way to examine the contents of this object is to plot it. First let’s examine the three rarefaction curves:
Now let’s consider the effect sizes as a function of scale
The grey polygons above represent the 95% quantile for the null models of no treatment effect.
Meyers et al. (2015) collected data on woody plants in the Missouri Ozarks. They collected 26 sites that had been recently burned and 26 sites that they considered unburned. We will reanalyze their data using the MoB framework.
# plant community in response to a prescribed fire treatment in a
# central US woodland
data(fire_comm)
data(fire_plot_attr)
fire_mob_in <- make_mob_in(fire_comm, fire_plot_attr,
coord_names = c('x', 'y'))
Now that the data is loaded and we have created a mob_in
object we can begin visualizing the patterns in the dataset. It is
always important to graph any dataset before attempting to analyze its
patterns. We will start our exploration with the sSBR.
par(mfrow=c(1,3))
plot_rarefaction(fire_mob_in, 'group', ref_level = 'unburned', 'IBR',
leg_loc = NA)
plot_rarefaction(fire_mob_in, 'group', ref_level = 'unburned', 'sSBR',
leg_loc = 'bottomright')
## Warning in plot_rarefaction(fire_mob_in, "group", ref_level = "unburned", :
## Sample based rarefaction methods do not make sense at alpha scale, dropping
## alpha scale curves
The sSBR indicates that the unburned site has higher species richness across all scales and it appears that the two sites differ in the rate of diversity accumulation at certain scales. Let’s examine the species-abundance distributions to see if they may have shifted and may be partially responsible for this observed shift in S.
oldpar <- par(no.readonly = TRUE)
par(mfrow = c(1, 2))
plot_abu(fire_mob_in, 'group', ref_level = 'unburned', 'rad', leg_loc = 'topright',)
plot_abu(fire_mob_in, 'group', ref_level = 'unburned', 'sad', leg_loc = NA)
Above we plot the SAD in two different ways. The plot on the left is the standard rank curve and the plot on the right is the cumulative curve which McGill (2011) advocates for using. The cumulative curve makes it particularly clear that the shape (i.e., evenness) between the treatments is really similar, but in the rank curve it does appear that the burned site does some sites that are highly dominated by a single species.
Let’s use the two-scale analysis to continue this exploration of the data and to test some hypotheses regarding which components are driving this decrease in S in the burned sites.
indices <- c('N', 'S', 'S_C', 'S_n', 'S_PIE')
fire_div <- tibble(fire_comm) %>%
group_by(group = fire_plot_attr$group) %>%
group_modify(~ calc_comm_div(.x, index = indices, effort = 5,
extrapolate = TRUE))
Let’s graphically examine the metrics:
It is clear that the fire decreased abundance of woody plants - that is likely not a surprise. The question remains if this drove the decreases in S we observed in the sSBR and which are obvious in the second set of panels on S. It is worth noting that that the decrease in S is only significant at the \(\alpha\)-scale, and that fire actually increases \(\beta\)-diversity. When we examine the pattern of Sn we see that the effect size is half of what it was for S at the \(\alpha\)-scale. indicating that the decrease in N is helping to decrease S. Also the significant increase in \(\beta_S\) is not as strong in \(\beta_{Sn}\) which indicates: 1) that the burned sites have higher turnover in part because they have fewer individuals, and 2) that there is a detectable increase in intra-specific aggregation in the burned sites because \(\beta_{Sn}\) is still higher in the burned site. SPIE indicates that their is a shift towards higher evenness in the unburned sites that is stronger at the \(\gamma\)-scale. So from the two-scale analysis we can conclude that fire: 1) decreases N which decreases S, 2) increases aggregation, and 3) decreases evenness.
Let’s now look at the multi-scale analysis to examine the
scale-dependence and relative strength of these effects. Note here we
set the argument log_scale
to TRUE
because
there is a large number of individuals and it is not necessary to
compute the differences between the curves at all possible scales.
fire_deltaS <- get_delta_stats(fire_mob_in, 'group', ref_level = 'unburned',
type = 'discrete', log_scale = TRUE, n_perm = 199,
overall_p = TRUE)
This time we’ll examine the full suite of graphics for the multimetric analysis.
## Effect size shown at the following efforts: 2, 4, 8, 16, 32, 64, 128, 256, 512
## Warning: No shared levels found between `names(values)` of the manual scale and the
## data's fill values.
These confirm our expectations based on the two-scale analysis. The IBR indicates the increase in evenness in the unburned site particularly at coarse scales, the nsSBR illustrates that the N-effect is fairly strong, and the sSBR shows that their are some effects of aggregation. The delta effect curves can show this more clearly. These plots illustrate that: 1. None of these individual effects are of a really large magnitude ((\(\Delta\)S is never more or less than 2 species). 2. The N-effect is the largest driver of decreases in S. 3. The increased aggregation in the burned sites is only really relevant at fine spatial scales. 4. Although evenness is lower in the burned sites it is only outside of the acceptance intervals at the finest spatial scales.
Here we reanalyze data from Chase (2010) in which freshwater aquatic communities of macroinvertebrates and juvenile amphibians in artificial pools (i.e., cattle tanks) were enriched with phosphorus or not.
data(tank_comm)
data(tank_plot_attr)
tank_mob_in <- make_mob_in(tank_comm, tank_plot_attr,
coord_names = c('x', 'y'))
## Warning in make_mob_in(tank_comm, tank_plot_attr, coord_names = c("x", "y")): Row names of community and plot attributes tables do not match
## which may indicate different identities or orderings of samples
The data is loaded let’s examine the sSBR.
## Warning in plot_rarefaction(tank_mob_in, "group", ref_level = "low", "sSBR"):
## Sample based rarefaction methods do not make sense at alpha scale, dropping
## alpha scale curves
Clearly enrichment had a big effect on species richness as it is larger in the “high” productivity (i.e., enriched) community compared to the “low” community at all scales. It is rare to see such a strong asymptote on a rarefaction curve but it does appear that no new species were being encountered in the low community.
oldpar <- par(no.readonly = TRUE)
par(mfrow = c(1, 2))
plot_abu(tank_mob_in, 'group', ref_level = 'low', 'rad')
plot_abu(tank_mob_in, 'group', ref_level = 'low', 'sad', leg_loc = NA)
The SAD plots indicate only a modest shift in the evenness component of the SAD although clearly from the sSBR we know that the size of the species pool is larger in the high community.
indices <- c('N', 'S', 'S_C', 'S_n', 'S_PIE')
tank_div <- tibble(tank_comm) %>%
group_by(group = tank_plot_attr$group) %>%
group_modify(~ calc_comm_div(.x, index = indices, effort = 5,
extrapolate = TRUE))
Let’s graphically examine the metrics:
The two-scale analysis indicates that enrichment does not affect N but that it does increase S but only at the coarse scale. The higher productivity sites had higher \(\beta_S\) indicating that species turnover was higher due to enrichment. The analysis of Sn indicated that this increase in turnover was due in part to an increase in spatial aggregation in the enriched tanks. SPIE indicated that the pattern of evenness particularly in common species was not changed by enrichment (as we observed in the plots of the SADs).
tank_deltaS <- get_delta_stats(tank_mob_in, 'group', ref_level = 'low',
inds = 10, log_scale = TRUE, type = 'discrete',
n_perm=199)
## Effect size shown at the following efforts: 2, 4, 8, 15, 15, 49, 180, 180, 662, 662, 2427, 2427
## Warning: No shared levels found between `names(values)` of the manual scale and the
## data's fill values.
The delta S plot indicates that enrichment increased intra-specific aggregation which resulted in decreased S, did not influence S via N, and did increase the size of the species pool which our framework identifies as an SAD effect. We know from our other analyses that this was not due to large changes in evenness.
This example is particularly interesting because: 1) there is absolutely no density effect, 2) the aggregation effects and SAD effects cancel each other out so strongly that a standard analysis of plot S indicates no change due to enrichment when obviously there are large changes to the community influencing richness.
Chase, J. M. (2010). Stochastic community assembly causes higher biodiversity in more productive environments. Science, 328: 1388-1391.
Chao, A., and L. Jost. 2012. Coverage-based rarefaction and extrapolation: standardizing samples by completeness rather than size. Ecology 93:2533–2547.
Chiu, C.-H., Wang, Y.-T., Walther, B.A. & Chao, A. (2014). An improved nonparametric lower bound of species richness via a modified good-turing frequency formula. Biometrics, 70, 671-682.
Gotelli, N.J. & Colwell, R.K. (2001). Quantifying biodiversity: procedures and pitfalls in the measurement and comparison of species richness. Ecology letters, 4, 379–391
Hurlbert, S.H. (1971). The Nonconcept of Species Diversity: A Critique and Alternative Parameters. Ecology, 52, 577–586
Jost, L. (2007). Partitioning Diversity into Independent Alpha and Beta Components. Ecology, 88, 2427-2439.
Myers, J. A., Chase, J. M., Crandall, R. M., & Jiménez, I. (2015). Disturbance alters beta‐diversity but not the relative importance of community assembly mechanisms. Journal of Ecology, 103(5), 1291-1299.
McGlinn, D.J. X. Xiao, F. May, S. Blowes, J. Chase, N. Gotelli, T. Knight, B. McGill, and O. Purschke. 2019. MoB (Measurement of Biodiversity): a method to separate the scale-dependent effects of species abundance distribution, density, and aggregation on diversity change. Methods in Ecology and Evolution. 10:258–269. https://doi.org/10.1111/2041-210X.13102
Powell, K.I., Chase, J.M. & Knight, T.M. (2013). Invasive Plants Have Scale-Dependent Effects on Diversity by Altering Species-Area Relationships. Science, 339, 316–318.