Code
# this is in the .GlobalEnv
<- 1
a environment() ## the current environment is .GlobalEnv
globalenv() ## the same
ls(envir = environment())
simList
- What is it?Eliot McIntire
June 20, 2024
See Barebones R script for the code shown in this chapter
In R
, there is a default environment, called the .GlobalEnv
. When you start typing in R and you create an object, it is “put” in the .GlobalEnv
The .GlobalEnv
is convenient to begin in R, but it quickly becomes limiting. We need more places to put objects, and we need a way to be more in control of the things that we want to keep, share, modify etc. In SpaDES
, this place is called the simList
. It is a rich data object that acts like a list or an environment, i.e., we can put objects into it and use them later.
simList
is an environment
The name simList
has the word “list” in it, but it is actually an environment
. The “sim” part of the name is historically inherited from “simulation” modelling, although you may want to do nothing of the sort with your SpaDES modules.
Accessing objects in the simList
can be done with $
or [["object_name"]]
and objects are manipulated as they would normally – e.g. if DF
is a data.frame
one would use sim$DF[1, 3]
to extract the value on the first row and third column.
There is no limit to the number of objects you can add to a simList
– the limit is, of course, your machine’s RAM.
simList
come from?There is only one way in SpaDES.core
to create a simList
:
simList
?A simList
object is simply a structured data type containing various elements.
The main components of a simList
are:
A list of modules used;
The event queue;
A description of the data (object) dependencies.
We can examine the simList
object structure in the usual R fashion by printing (show
ing) it, or by using str()
:
simList
s are S4 objects, so we can use getSlots()
and slotNames()
to examine the object.
See also ?'simList-class'
simList
The simList
can be imagined as a file cabinet where all the simulation details and objects (i.e. the parameters, inputs and outputs declared by each module) are stored neatly and in an easily accessible way.
simList
objectWhat are the names of each of the slots in the simList?
What do each of these slots contain?
Hint: see ?'simList-class'
simList
accessor functionssimList
accessor functions are used to determine the following:
the modules included in the simulation and their package dependencies;
the global parameter values used;
the module-specific parameter values used;
the simulation start, end and current times;
the time units used by the modules in the simulation;
the scheduled and completed event queues;
the objects (functions, data, etc.) used in the simulation;
the file paths used for simulation inputs and outputs.
We will try this with the simple linear module first, for which we’ve already defined default values for the input object x
(see Chapter 5).
# Get the sample modules that come with SpaDES.core
modulePath <- getSampleModules(tempdir())
# options(spades.loadReqdPkgs = FALSE) # we don't need to check for packages in this example
modulePath <- "~/SpaDES_book/NewModuleIntro/NewModule"
mySim <- simInit(params = list("My_linear_model" = list(length = 20)),
modules = "My_linear_model",
paths = list(modulePath = modulePath))
events(mySim)
# b is in the .xData slot
mySim$x
mySim@.xData$x
# all functions below come from SpaDES.core::
# list modules used in the simulation
modules(mySim)
# list module dependencies and packages used
depends(mySim)
packages(mySim)
# list global and module-specific param values
params(mySim)
P(mySim) # bonus: how do params() and P() differ?
# list start and end times
times(mySim)
start(mySim)
end(mySim)
## and the 'current' time
time(mySim)
# get the simulation and module timeunits
timeunit(mySim)
timeunits(mySim)
# get the scheduled and completed event queues
events(mySim)
completed(mySim)
# list the objects (functions, data, etc.) stored in the simList
objects(mySim)
# list the file paths used in the simulation
paths(mySim)
inputPath(mySim)
outputPath(mySim)
Now run the simulation
simNew <- sim
doesn’t copy
If you don’t know what an environment
is in R
, it is OK. The most important feature of an environment
is that it employs pass-by-reference
, which means it is not copied when it is “assigned” somewhere. This makes SpaDES
fast enough to use for huge workflows.
simList
before and after spades()
Repeat the above with more complex modules. Use the accessor functions to look at what inside the simList
and try passing different parameter values or inputs.
# this is in the .GlobalEnv
a <- 1
environment() ## the current environment is .GlobalEnv
globalenv() ## the same
ls(envir = environment())
Require::Require(c("reproducible", "SpaDES.core (>= 2.1.5)"),
repos = c("https://predictiveecology.r-universe.dev", getOption("repos")))
sim <- simInit()
sim$a <- 1
sim$b <- sim$a + 2
sim$b
SpaDES.core::envir(sim)
sim <- simInit()
is(sim, "environment")
# [1] TRUE
emptySim <- SpaDES.core::simInit()
emptySim # same as show(emptySim)
str(emptySim)
emptySim <- simInit()
str(emptySim)
slotNames(emptySim)
getSlots('simList')
?`simList-class`
# Get the sample modules that come with SpaDES.core
modulePath <- getSampleModules(tempdir())
# options(spades.loadReqdPkgs = FALSE) # we don't need to check for packages in this example
modulePath <- "~/SpaDES_book/NewModuleIntro/NewModule"
mySim <- simInit(params = list("My_linear_model" = list(length = 20)),
modules = "My_linear_model",
paths = list(modulePath = modulePath))
events(mySim)
# b is in the .xData slot
mySim$x
mySim@.xData$x
# all functions below come from SpaDES.core::
# list modules used in the simulation
modules(mySim)
# list module dependencies and packages used
depends(mySim)
packages(mySim)
# list global and module-specific param values
params(mySim)
P(mySim) # bonus: how do params() and P() differ?
# list start and end times
times(mySim)
start(mySim)
end(mySim)
and the 'current' time
time(mySim)
# get the simulation and module timeunits
timeunit(mySim)
timeunits(mySim)
# get the scheduled and completed event queues
events(mySim)
completed(mySim)
# list the objects (functions, data, etc.) stored in the simList
objects(mySim)
# list the file paths used in the simulation
paths(mySim)
inputPath(mySim)
outputPath(mySim)
mySimOut <- reproducible::Copy(mySim) # make a deep copy of the simList
mySimOut <- spades(mySimOut)
sim <- simInit()
sim$a <- 1
simNew <- sim
simNew$a <- 2
# what value will this have?
sim$a
times(mySim)
times(mySimOut)
objects(mySim)
objects(mySimOut)
modulePath <- getSampleModules(tempdir())
# options(spades.loadReqdPkgs = FALSE) # we don't need to check for packages in this example
mySim <- simInit(modules = dir(modulePath[1:3]),
paths = list(modulePath = modulePath),
objects = list(b = 1))
simOut <- spades(mySim)
Note that simInitAndSpades
calls simInit
internally↩︎