The introduction employed a simplistic expemple of food web to familiarize the user with the basic commands and options of the EcoDiet package. Here we will use a more realistic example (although still artificial!) to run the different EcoDiet configurations, compare their results and hence higlight the complementarity in the different data used.
The data corresponds to 10 trophic groups with stomach content data, and very distinct isotopic measures.
<- system.file("extdata", "realistic_stomach_data.csv",
realistic_stomach_data_path package = "EcoDiet")
<- read.csv(realistic_stomach_data_path)
realistic_stomach_data ::kable(realistic_stomach_data) knitr
X | Cod | Pout | Sardine | Shrimps | Crabs | Bivalves | Worms | Zooplankton | Phytoplankton | Detritus |
---|---|---|---|---|---|---|---|---|---|---|
Cod | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Pout | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Sardine | 9 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Shrimps | 4 | 4 | 29 | 0 | 24 | 0 | 0 | 0 | 0 | 0 |
Crabs | 1 | 24 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Bivalves | 0 | 3 | 0 | 0 | 11 | 0 | 0 | 0 | 0 | 0 |
Worms | 16 | 30 | 0 | 1 | 24 | 0 | 0 | 0 | 0 | 0 |
Zooplankton | 0 | 27 | 6 | 3 | 0 | 0 | 0 | 0 | 0 | 0 |
Phytoplankton | 0 | 0 | 14 | 10 | 0 | 16 | 0 | 20 | 0 | 0 |
Detritus | 0 | 0 | 0 | 12 | 19 | 18 | 18 | 0 | 0 | 0 |
full | 21 | 30 | 29 | 19 | 29 | 27 | 18 | 20 | 0 | 0 |
<- system.file("extdata", "realistic_biotracer_data.csv",
realistic_biotracer_data_path package = "EcoDiet")
<- read.csv(realistic_biotracer_data_path)
realistic_biotracer_data ::kable(realistic_biotracer_data[c(1:3, 31:33, 61:63), ]) knitr
group | d13C | d15N | |
---|---|---|---|
1 | Cod | -12.94144 | 19.18913 |
2 | Cod | -14.96070 | 20.23939 |
3 | Cod | -13.77822 | 19.48809 |
31 | Pout | -13.47127 | 18.57353 |
32 | Pout | -13.16888 | 17.58714 |
33 | Pout | -14.23085 | 17.38938 |
61 | Sardine | -14.56111 | 16.95231 |
62 | Sardine | -15.04729 | 17.15197 |
63 | Sardine | -14.63688 | 16.90906 |
library(EcoDiet)
plot_data(biotracer_data = realistic_biotracer_data,
stomach_data = realistic_stomach_data)
#> Warning in plot_matrix(stomach_data, title = "Proportion of occurences in
#> stomachs", : NAs introduced by coercion
#> Warning in rev(as.numeric(df$prey)): NAs introduced by coercion
#> Warning: Removed 100 rows containing missing values (geom_raster).
#> Warning: Removed 25 rows containing missing values (geom_text).
#> Warning: Position guide is perpendicular to the intended axis. Did you mean to specify a different guide `position`?
#> Position guide is perpendicular to the intended axis. Did you mean to specify a different guide `position`?
#> Warning: Use of `biotracer_data$group` is discouraged. Use `group` instead.
Yes, we are aware that isotopic data is usually messier, but isn’t it a beautiful plot?
We define the configuration we are in, and preprocess the data:
<- FALSE
literature_configuration
<- preprocess_data(biotracer_data = realistic_biotracer_data,
data trophic_discrimination_factor = c(0.8, 3.4),
literature_configuration = literature_configuration,
stomach_data = realistic_stomach_data)
#> The model will investigate the following trophic links:
#> Bivalves Cod Crabs Detritus Phytoplankton Pout Sardine Shrimps
#> Bivalves 0 0 1 0 0 1 0 0
#> Cod 0 0 0 0 0 0 0 0
#> Crabs 0 1 0 0 0 1 0 0
#> Detritus 1 0 1 0 0 0 0 1
#> Phytoplankton 1 0 0 0 0 0 1 1
#> Pout 0 1 0 0 0 0 0 0
#> Sardine 0 1 0 0 0 0 0 0
#> Shrimps 0 1 1 0 0 1 1 0
#> Worms 0 1 1 0 0 1 0 1
#> Zooplankton 0 0 0 0 0 1 1 1
#> Worms Zooplankton
#> Bivalves 0 0
#> Cod 0 0
#> Crabs 0 0
#> Detritus 1 0
#> Phytoplankton 0 1
#> Pout 0 0
#> Sardine 0 0
#> Shrimps 0 0
#> Worms 0 0
#> Zooplankton 0 0
In this configuration, priors are set for each trophic link identified as plausible by the user but the priors are not informed by literature data, and are thus uninformative:
plot_prior(data, literature_configuration)
#> Warning in plot_matrix(mean_prior, title, save, save_path): NAs introduced by
#> coercion
#> Warning in rev(as.numeric(df$prey)): NAs introduced by coercion
#> Warning: Removed 100 rows containing missing values (geom_raster).
#> Warning: Removed 25 rows containing missing values (geom_text).
#> Warning: Position guide is perpendicular to the intended axis. Did you mean to specify a different guide `position`?
#> Position guide is perpendicular to the intended axis. Did you mean to specify a different guide `position`?
#> Warning in plot_matrix(mean_prior, title, save, save_path): NAs introduced by
#> coercion
#> Warning in rev(as.numeric(df$prey)): NAs introduced by coercion
#> Warning: Removed 100 rows containing missing values (geom_raster).
#> Warning: Removed 25 rows containing missing values (geom_text).
#> Warning: Position guide is perpendicular to the intended axis. Did you mean to specify a different guide `position`?
#> Position guide is perpendicular to the intended axis. Did you mean to specify a different guide `position`?
The marginal prior distributions have different shape depending on the variables:
it is flat or uniform for \(\eta\), the probabilities that a trophic link exists (all the probabilities of existence are thus equiprobable),
the marginal distributions for each diet proportion \(\Pi\) are peaking at zero, although the joint distribution for \(\Pi\)s is a flat Dirichlet prior, because all the diet proportions must sum to one.
plot_prior(data, literature_configuration, pred = "Pout")
We define the model, and test if it compiles well with a few iterations and adaptation steps:
<- write_model(literature_configuration = literature_configuration)
model_string
<- run_model(textConnection(model_string), data, nb_adapt = 1e1, nb_iter = 1e2)
mcmc_output #> Compiling model graph
#> Resolving undeclared variables
#> Allocating nodes
#> Graph information:
#> Observed stochastic nodes: 316
#> Unobserved stochastic nodes: 125
#> Total graph size: 1104
#>
#> Initializing model
#> Warning in rjags::jags.model(file = model_file, data = data, inits = inits, :
#> Adaptation incomplete
#> The model took 0.26 secs to be initialized.
#> NOTE: Stopping adaptation
#> The model took 1.69 secs to run.
#>
#> /!\ CONVERGENCE PROBLEM /!\
#> Out of the 50 variables, 24 variables have a Gelman-Rubin statistic > 1.1.
#> You should increase the number of iterations of your model with the `nb_iter` argument.
You should now try to run the model until it converges (it should take around half an hour to run, so we won’t do it in this vignette):
<- run_model(textConnection(model_string), data, nb_adapt = 1e3, nb_iter = 1e5) mcmc_output
Here are the figures corresponding to the results that have converged:
plot_results(mcmc_output, data)
plot_results(mcmc_output, data, pred = "Pout")
You can also plot the results for specific prey if you want a clearer figure:
plot_results(mcmc_output, data, pred = "Pout",
variable = "PI", prey = c("Bivalves", "Worms"))
We now change the configuration to add literature data to the model:
<- TRUE literature_configuration
<- system.file("extdata", "realistic_literature_diets.csv",
realistic_literature_diets_path package = "EcoDiet")
<- read.csv(realistic_literature_diets_path)
realistic_literature_diets ::kable(realistic_literature_diets) knitr
X | Cod | Pout | Sardine | Shrimps | Crabs | Bivalves | Worms | Zooplankton | Phytoplankton | Detritus |
---|---|---|---|---|---|---|---|---|---|---|
Cod | 0.0000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0 | 0.0 | 0 | 0 |
Pout | 0.4275065 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0 | 0.0 | 0 | 0 |
Sardine | 0.3603675 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0 | 0.0 | 0 | 0 |
Shrimps | 0.0300737 | 0.5295859 | 0.0002143 | 0.0000000 | 0.0082107 | 0.0000000 | 0.0 | 0.0 | 0 | 0 |
Crabs | 0.1410430 | 0.3332779 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0 | 0.0 | 0 | 0 |
Bivalves | 0.0000000 | 0.0006130 | 0.0000000 | 0.0000000 | 0.3441081 | 0.0000000 | 0.0 | 0.0 | 0 | 0 |
Worms | 0.0410093 | 0.1023676 | 0.0000000 | 0.0171336 | 0.4435377 | 0.0000000 | 0.0 | 0.0 | 0 | 0 |
Zooplankton | 0.0000000 | 0.0341557 | 0.7381375 | 0.9121505 | 0.0000000 | 0.0000000 | 0.0 | 0.0 | 0 | 0 |
Phytoplankton | 0.0000000 | 0.0000000 | 0.2616482 | 0.0000610 | 0.0000000 | 0.9966847 | 0.0 | 1.0 | 0 | 0 |
Detritus | 0.0000000 | 0.0000000 | 0.0000000 | 0.0706550 | 0.2041434 | 0.0033153 | 1.0 | 0.0 | 0 | 0 |
pedigree | 0.8000000 | 0.1000000 | 0.5000000 | 0.3000000 | 0.7000000 | 0.1000000 | 0.2 | 0.2 | 1 | 1 |
<- preprocess_data(biotracer_data = realistic_biotracer_data,
data trophic_discrimination_factor = c(0.8, 3.4),
literature_configuration = literature_configuration,
stomach_data = realistic_stomach_data,
literature_diets = realistic_literature_diets,
nb_literature = 12,
literature_slope = 0.5)
#> The model will investigate the following trophic links:
#> Bivalves Cod Crabs Detritus Phytoplankton Pout Sardine Shrimps
#> Bivalves 0 0 1 0 0 1 0 0
#> Cod 0 0 0 0 0 0 0 0
#> Crabs 0 1 0 0 0 1 0 0
#> Detritus 1 0 1 0 0 0 0 1
#> Phytoplankton 1 0 0 0 0 0 1 1
#> Pout 0 1 0 0 0 0 0 0
#> Sardine 0 1 0 0 0 0 0 0
#> Shrimps 0 1 1 0 0 1 1 0
#> Worms 0 1 1 0 0 1 0 1
#> Zooplankton 0 0 0 0 0 1 1 1
#> Worms Zooplankton
#> Bivalves 0 0
#> Cod 0 0
#> Crabs 0 0
#> Detritus 1 0
#> Phytoplankton 0 1
#> Pout 0 0
#> Sardine 0 0
#> Shrimps 0 0
#> Worms 0 0
#> Zooplankton 0 0
Now we see that the prior distributions are informed by the literature data:
when the literature diet input is > 0, the trophic link probabilities \(\eta\) are shifted toward one. Here this is the case for all prey but we could imagine that the user identify a species as a plausible prey whereas it has not been observed being consumed by the predator in the literature. In that case, the literature diet of 0 would drive \(\eta\) toward 0.
the average prior for the diet proportions \(\Pi\) is directly the literature diet input.
plot_prior(data, literature_configuration)
#> Warning in plot_matrix(mean_prior, title, save, save_path): NAs introduced by
#> coercion
#> Warning in rev(as.numeric(df$prey)): NAs introduced by coercion
#> Warning: Removed 100 rows containing missing values (geom_raster).
#> Warning: Removed 25 rows containing missing values (geom_text).
#> Warning: Position guide is perpendicular to the intended axis. Did you mean to specify a different guide `position`?
#> Position guide is perpendicular to the intended axis. Did you mean to specify a different guide `position`?
#> Warning in plot_matrix(mean_prior, title, save, save_path): NAs introduced by
#> coercion
#> Warning in rev(as.numeric(df$prey)): NAs introduced by coercion
#> Warning: Removed 100 rows containing missing values (geom_raster).
#> Warning: Removed 25 rows containing missing values (geom_text).
#> Warning: Position guide is perpendicular to the intended axis. Did you mean to specify a different guide `position`?
#> Position guide is perpendicular to the intended axis. Did you mean to specify a different guide `position`?
plot_prior(data, literature_configuration, pred = "Pout")
Again, we verify that the model compiles well:
<- write_model(literature_configuration = literature_configuration)
model_string
<- run_model(textConnection(model_string), data, nb_adapt = 1e1, nb_iter = 1e2)
mcmc_output #> Compiling model graph
#> Resolving undeclared variables
#> Allocating nodes
#> Graph information:
#> Observed stochastic nodes: 316
#> Unobserved stochastic nodes: 125
#> Total graph size: 1594
#>
#> Initializing model
#> Warning in rjags::jags.model(file = model_file, data = data, inits = inits, :
#> Adaptation incomplete
#> The model took 0.23 secs to be initialized.
#> NOTE: Stopping adaptation
#> The model took 1.59 secs to run.
#>
#> /!\ CONVERGENCE PROBLEM /!\
#> Out of the 50 variables, 23 variables have a Gelman-Rubin statistic > 1.1.
#> You should increase the number of iterations of your model with the `nb_iter` argument.
You should now try to run the model until it converges (it should take around half an hour to run, so we won’t do it in this vignette):
<- run_model(textConnection(model_string), data, nb_adapt = 1e3, nb_iter = 1e5) mcmc_output
Here are the figures corresponding to the results that have converged:
plot_results(mcmc_output, data)
plot_results(mcmc_output, data, pred = "Pout")
You can save the figures as PNG using:
plot_results(mcmc_output, data, pred = "Pout", save = TRUE, save_path = ".")