## Loops

• A fundamental unit of computer programs is the loop
• Used in virtually every computer language
• However, with R and SpaDES, there are 2 reasons not to:

• They are somewhat slow
• They don’t allow easy sharing of code
• Using SpaDES, and building this module, will not affect the first point – loops in R and any discrete event simulator will be “slow”

## Loops in time

• Some loops are used where time is the object being looped over
• i.e., each iteration of the loop is moving forward in time
• If one loop iteration depends on the previous loop iteration, it is called a Markov Chain
age <- 1
for (time in 1:10) {
age <- age + 1
}

## Events

• Rather than “iterating”, we can think of “events”
• Spring thaw

• Brainstorm events…

• Rather than for ..., we schedule the next event
• It would be something like this:
age <- 1

# define event
aging <- age + 1

events <- {
doEvent("aging")
scheduleEvent("aging", when = now + 1)
}

times = list(start = 1, end = 10) 

We will pull this apart next.

## Parts of a loop

Recall:

age <- 1
for (time in 1:10) {
age <- age + 1
}
• Setting up (sometimes required), initializing
age <- 1
• deciding on bounds and intermediates or “step”
• lower bound = 1 to upper bound = 10
• here step is 1 (i.e., 1, 2, 3, 4, … 10)
... in 1:10
• content
age <-  age + 1

## Moving to events

• Need same as a loop:

initialize, bounds, step, content

age <- 1                                 # Initialize

# define event
aging <- function(age) {
age <- age + 1                         # content
scheduleEvent("aging", when = now + 1) # step
}

times = list(start = 1, end = 10)        # bounds
• This creates a queue – a list of events that need to occur

## What would that sequence look like?

1. what is happening now
2. What are the next thing(s) in the queue
    eventTime moduleName  eventType
1:         0       loop       init
12:        10       loop addOneYear 

## Why would we want to do this?

• It is clean, transparent
• It is “modular” (what does that mean?)
• Can be very rich sequences including

• conditional scheduling
• irregular sequences
• the sequence changes mid-stream

## How to do that in SpaDES

• create a new “empty” module
• we will put the pieces in specific places so it works
newModule("loop", path = getwd())
# This will make a new module, and
#  tell you how to open it in the message 
• Open the module – the file that ends with .R

## Simple module

• Comes with 2 files, an .R file and a .Rmd file
• The .R. file has this in it - can we recognize the pieces?
doEvent.loop = function(sim, eventTime, eventType, debug = FALSE) {
switch(
eventType,
init = {
sim$age <- 1 sim <- scheduleEvent(sim, start(sim), "loop", "addOneYear") }, addOneYear = { sim$age <- sim$age + 1 sim <- scheduleEvent(sim, time(sim) + 1, "loop", "addOneYear") }, ) return(invisible(sim)) } ## The .Rmd file • Normally in an R project, we have a file open that we write our script in • Some of us use a .R file, some already use a .Rmd file • You can use either – but our default is .Rmd because you can write text around the code • We define a few things • paths (i.e., directories) • modules (e.g., “loop”) • times (i.e., start and end) • We parse/initialize the module (simInit) • We hit “run” (actually the function is called spades) • Sensible defaults come with the newModule function ## The .Rmd file contents times <- list(start = 1, end = 10) modulePath <- file.path("C:/Eliot") modules <- list("loop") ## Compare Loop and Event versions • For simple case here, loop is very short, event version is long # Loops age <- 1 for (time in 1:10) { age <- age + 1 } # Event mySim <- simInit(times = times, modules = modules, paths = list(modulePath = "C:/Eliot/GitHub/SpaDES.Workshops")) mySimOut <- spades(mySim, debug = TRUE) # Compare them -- yes! mySimOut$age
age

## Make your own loop module

• You will need:

• SpaDES loaded
• newModule( )
• open the .Rmd file
• open the .R file
• create an initial value of an object in the init event
• create a loop event
• do something to that object in the loop event
• scheduleEvent( ) for the next time in the future
• time(sim) gives you current time in the simulation