Run large-scale (i.e., ensemble) simulations of stock-and-flow models, varying initial
conditions and/or constants specified in conditions.
Usage
ensemble(
object,
n = 10,
conditions = NULL,
cross = TRUE,
central,
spread,
quantiles,
quiet = FALSE,
...
)Arguments
- object
Stock-and-flow model, object of class
stockflow.- n
Number of simulations to run in the ensemble. When conditions is specified, n defines the number of simulations to run per condition. If each condition only needs to be run once, set
n = 1. Defaults ton = 10.- conditions
A named list specifying fixed values for ensemble conditions. Names must correspond to stocks or constants in the model. Each list element should be a numeric vector of values to test.
If cross =
TRUE(default), all combinations of values are generated. For example,list(param1 = c(1, 2), param2 = c(10, 20))creates 4 conditions:(1,10), (1,20), (2,10), (2,20).If cross =
FALSE, values are paired element-wise, requiring all vectors to have equal length. For example,list(param1 = c(1, 2, 3), param2 = c(10, 20, 30))creates 3 conditions:(1,10), (2,20), (3,30). Defaults toNULL(no parameter variation).- cross
If
TRUE, cross the parameters in the conditions list to generate all possible combinations of parameters. Defaults toTRUE.- central
Which central-tendency statistic(s) to compute across the simulations at each time point: any of
"mean","median", or"none". Each one becomes a column of the same name insummary. Defaults to the model'scentralsetting (seesim_settings()); set it here to override that for this run. Note thatcentralandspreadchoose what is computed;plot.ensemble_stockflow()then chooses what to show.- spread
Which measures of spread to compute:
"quantile"(columnsquant1,quant2, ... at the probabilities inquantiles),"sd","range"(aminand amaxcolumn), or"none". Several can be combined, e.g.c("quantile", "sd"). Defaults to the model'sspreadsetting.- quantiles
Probabilities for the quantile columns, used when
spreadincludes"quantile", e.g.c(0.025, 0.975). They become columnsquant1,quant2, ... in the order given (so herequant1is the 2.5% quantile andquant2the 97.5%); the probabilities themselves are kept insims$quantiles. Defaults to the model'squantilessetting.- quiet
If
TRUE, suppress informational messages such as progress and status updates. Warnings and errors are always shown. Defaults toFALSE. R ensembles show a cli progress bar viaprogressr::handler_cli(), including when simulations run through a parallelfuture::plan().- ...
Optional arguments passed to
sim_settings(); these can be used to override the simulation specifications set in the model object.
Value
Object of class ensemble_stockflow, which is a list
containing:
- success
If
TRUE, simulation was successful. IfFALSE, simulation failed.- error_message
If success is
FALSE, contains the error message.- df
data.frame with simulation results in long format, if save_sims is
TRUE. The iteration number is indicated by column "sim". If conditions was specified, the condition is indicated by column "condition".- summary
data.frame with summary statistics of the ensemble. Contains the statistics requested via
centralandspread(as columns named after each statistic, plusquant1,quant2, ... whenspreadincludes"quantile"), as well as amissing_countcolumn. If conditions was specified, summary statistics are calculated for each condition in the ensemble.- n
Number of simulations run in the ensemble (per condition if conditions is specified).
- n_total
Total number of simulations run in the ensemble (across all conditions if conditions is specified).
- n_conditions
Total number of conditions.
- conditions
data.frame with the conditions used in the ensemble, if conditions was specified.
- init
List with df (if save_sims = TRUE) and summary, containing data.frame with the initial values of the stocks used in the ensemble.
- constants
List with df (if save_sims = TRUE) and summary, containing data.frame with the constant parameters used in the ensemble.
- script
Script used for the ensemble simulation.
- duration
Duration of the simulation in seconds.
- ...
Other parameters passed to ensemble
Details
It is strongly recommended to reduce the size of the simulation output by
saving fewer values with save_by, save_times, or save_length in
sim_settings().
By default, only summary statistics across simulations are returned.
To return individual simulations, set save_sims = TRUE in sim_settings() or
pass save_sims = TRUE via ... in ensemble().
Note that returning individual simulations can consume a lot of memory for large ensembles.
For simulations in Julia, the ensemble can be run in parallel using multiple threads
by setting nthreads in use_julia(). For simulations in R, use
future::plan() to control parallel execution.
To create a reproducible ensemble simulation, set a seed using sim_settings().
If you do not see any variation within a condition of the ensemble (i.e., the confidence bands are virtually non-existent), there are likely no random elements in your model. Without these, there can be no variability in the model. Try specifying a random initial condition or adding randomness to other model elements (see examples).
Examples
# Ensemble simulation in R (no parallelization)
# Load example
sfm <- stockflow("predator_prey")
# Set random initial conditions
sfm <- update(sfm, c(predator, prey),
eqn = runif(1, min = 20, max = 80)
)
# For ensemble simulations, it is highly recommended to reduce the
# returned output. For example, to save only 20 values per simulation:
sfm <- sim_settings(sfm, save_length = 20)
# Run ensemble simulation with a small number of simulations
sims <- ensemble(sfm, n = 3)
#> Starting ensemble simulation in "R" with 3 simulations.
#> ✔ Ensemble simulation completed in 1.7592 seconds.
if (interactive()) plot(sims)
# To plot individual trajectories, rerun the ensemble with save_sims = TRUE.
# Note that this can consume a lot of memory for large simulations.
sims <- ensemble(sfm, n = 10, save_sims = TRUE)
#> Starting ensemble simulation in "R" with 10 simulations.
#> ✔ Ensemble simulation completed in 5.8468 seconds.
plot(sims, which = "sims")
# Specify which trajectories to plot
plot(sims, which = "sims", sim = 1)
# Plot the median with lighter individual trajectories
plot(sims, central = "median", which = "sims", alpha = 0.1)
# For larger ensembles, we can use parallelization with future
future::plan(future::multisession, workers = 4)
# Ensembles can also be run with exact values for the initial conditions
# and parameters. Below, we vary the initial values of the predator and the
# birth rate of the predators (delta). We generate a hundred samples per
# condition. By default, the parameters are crossed, meaning that all
# combinations of the parameters are run.
sims <- ensemble(sfm,
n = 50,
conditions = list(predator = c(10, 50), delta = c(.025, .05))
)
#> Starting ensemble simulation in "R" with 200 simulations in total.
#> ℹ 4 conditions x 50 simulations per condition.
#> ✔ Ensemble simulation completed in 47.4199 seconds.
plot(sims)
# By default, a maximum of nine conditions is plotted.
# Plot specific conditions:
plot(sims, condition = c(1, 3), nrows = 1)
# Generate a non-crossed design, where the length of each conditions vector
# needs to be equal:
sims <- ensemble(sfm,
n = 10, cross = FALSE,
conditions = list(
predator = c(10, 20, 30),
delta = c(.020, .025, .03)
)
)
#> Starting ensemble simulation in "R" with 30 simulations in total.
#> ℹ 3 conditions x 10 simulations per condition.
#> ✔ Ensemble simulation completed in 7.4948 seconds.
plot(sims, nrows = 3)
# Stop parallelization after use
future::plan(future::sequential)