Direct Transmission Modes - Practice

#load various variable definitions that are the same for each app
source('startup_script.R')
currentrmdfile = knitr::current_input() 
#currentrmdfile = "basicsir_documentation.Rmd" # For debugging
appsettings = get_settings(currentrmdfile,appdocdir,packagename)

Overview {#shinytab1}

This app allows you to explore a model with 2 different modes of direct transmission. Read about the model in the "Model" tab. Then do the tasks described in the "What to do" tab.

Learning Objectives

The Model {#shinytab2}

Model Overview

This is a simple SIR model with births and deaths and 2 types of direct transmission, density-dependent and frequency-dependent (based on the terminology in [@begon02] - see Further Information tab for references).

This model has the following compartments:

The processes being modeled are:

The force of infection, denoted by f here, depends on the transmission model. For density-dependent transmission, it is given by f = b~d~ I / A, where A is the area of the scenario under consideration (e.g. a city). For frequency-dependent transmission, we have f = b~f~ I / N, where N is the size of the population, N=S+I+R.

Model Implementation

The flow diagram and the set of ordinary differential equations (ODE) which are used to implement this model are as follows:

knitr::include_graphics(here::here('inst/media',appsettings$modelfigname))

$$\dot S =n - f S + wR - mS$$ $$\dot I = f S - g I - mI$$ $$\dot R = g I - wR - mR$$

with f = b~d~ I / A for density-dependent transmission and f = b~f~ I / N for frequency-dependent transmission.

Model Comments

Note that quite often, we assume that the area is constant and do not include it in the model or even talk about it. Often, the population size is also assumed to be constant. In that case, the 2 types of transmission models behave the same. But as soon as area or population size change, the model results differ. This is the topic covered here.

What to do {#shinytab3}

The tasks below are described in a way that assumes everything is in units of MONTHS (rate parameters, therefore, have units of inverse months). If any quantity is not given in those units, you need to convert it first (e.g. if it says a year, you need to convert it to 12 months).

#this is the running counter for the records which starts at 1 
rc=1

#empty object, will hold all outcomes
alloutcomes = NULL

# Task 1
tid = 1
tasktext = "Run the simulation with 999 susceptible individuals and 1 initially infected host. Set the simulation duration to 10 years. Consider density-dependent transmission, with a transmission rate of _b~d~_ = 0.005, and an area of size 2. Assume that the duration of the infectious period is 15 days long (and that there are 30 days in a month). Turn off births, deaths and waning immunity for now. If you did it correctly, your outbreak should end with around 626 susceptible individuals still remaining. Take a look at the force of infection (FOI) equation for density-dependent transmission. The FOI value changes throughout the outbreak because it has _I_ in the equation. But the other parts of the equation remain constant. Compute the FOI value for the settings here at the start of the outbreak (where I=1)."

# Record for task 1
nrec = 2 # number of items to record
out_records = c("Force of infection at start",
                "FRACTION of susceptible (Sfinal/Sinitial) at end of simulation")
out_types = c("Numeric","Rounded_Numeric")
out_notes = c("Report all digits","Round to 2 significant digits (0.XX)")
outcomes = data.frame( TaskID = rep(tid,nrec),
                       TaskText = rep(tasktext,nrec),
                      RecordID = paste0('T',tid,'R',(1:nrec)),
                      Record = out_records, 
                      Type = out_types, 
                      Note = out_notes)
alloutcomes = rbind(alloutcomes,outcomes)
rc = rc + nrec #increment record counter by number of outcomes to record for this task 


# Task 2
tid = 2
tasktext = "Now switch the scenario to frequency-dependent from density-dependent transmission. Set _b~f~_ = 2.5. The value of _b~d~_ does not matter since only one type of transmission is turned on at any time. Leave all other settings as before. Before you run the simulation, compute the force of infection for frequency-dependent transmission for the chosen parameter values. Compare to the value from the previous task. Based on that, what do you expect to get for the outbreak? Run the simulation to confirm your expectation."

# Record for task 2
nrec = 2 # number of items to record
out_records = c("Force of infection at start",
                "FRACTION of susceptible at end of simulation")
out_types = c("Numeric","Rounded_Numeric")
out_notes = c("Report all digits","Round to 2 significant digits (0.XX)")
outcomes = data.frame( TaskID = rep(tid,nrec),
                       TaskText = rep(tasktext,nrec),
                      RecordID = paste0('T',tid,'R',(1:nrec)),
                      Record = out_records, 
                      Type = out_types, 
                      Note = out_notes)
alloutcomes = rbind(alloutcomes,outcomes)
rc = rc + nrec #increment record counter by number of outcomes to record for this task 


### Task 3 
tid = 3
tasktext = "Let's assume we are now in a location with twice the number of people as before (_S~0~_ = 1999), living in the same area. All other quantities (rate of transmission, recovery time, etc.) are assumed to be the same. Take a look at the FOI equation for density-dependent transmission. Based on its value for this new scenario, how do you expect the outbreak to change if transmission is density-dependent? Note that you will need to consider not only the FOI at the start (with _I_=1), but also how _I_, and thus the FOI, change over the course of the outbreak, and how this is impacted by a change in population size. Run the simulation to check your expectations."


# Record for task 3
out_records = c("Force of infection at start",
                "FRACTION of susceptible at end of simulation")
out_types = c("Numeric","Rounded_Numeric")
out_notes = c("Report all digits","Round to 2 significant digits (0.XX)")
outcomes = data.frame( TaskID = rep(tid,nrec),
                       TaskText = rep(tasktext,nrec),
                      RecordID = paste0('T',tid,'R',(1:nrec)),
                      Record = out_records, 
                      Type = out_types, 
                      Note = out_notes)
alloutcomes = rbind(alloutcomes,outcomes)
rc = rc + nrec #increment record counter by number of outcomes to record for this task 

### Task 4 
tid = 4
tasktext = "Repeat what you did for the previous task, now assuming that transmission is frequency-dependent."
out_records = c("Force of infection at start",
                "FRACTION of susceptible at end of simulation")
out_types = c("Numeric","Rounded_Numeric")
out_notes = c("Report all digits","Round to 2 significant digits (0.XX)")
outcomes = data.frame( TaskID = rep(tid,nrec),
                       TaskText = rep(tasktext,nrec),
                      RecordID = paste0('T',tid,'R',(1:nrec)),
                      Record = out_records, 
                      Type = out_types, 
                      Note = out_notes)
alloutcomes = rbind(alloutcomes,outcomes)
rc = rc + nrec #increment record counter by number of outcomes to record for this task 

#########################
### Task 5
#########################
tid = 5
tasktext = "If you double the population size as you just did, how do you need to adjust the area to obtain an outbreak of the same relative size (same fraction that become infected/remain susceptible) for density-dependent transmission? Try with the simulation and see if your expectation is correct."
nrec = 1 # number of items to record
out_records = c("The area used to get the same final fraction susceptible as in task 1.")
out_types = c("Rounded_Integer")
out_notes = c("Report the rounded integer")
outcomes = data.frame( TaskID = rep(tid,nrec),
                       TaskText = rep(tasktext,nrec),
                      RecordID = paste0('T',tid,'R',(1:nrec)),
                      Record = out_records, 
                      Type = out_types, 
                      Note = out_notes)
alloutcomes = rbind(alloutcomes,outcomes)
rc = rc + nrec #increment record counter by number of outcomes to record for this task 

#########################
### Task 6
#########################
tid = 6
tasktext = "Keep exploring by trying different parameters and transmission settings and see how they influence results. You can also go beyond a single outbreak and turn on births/deaths (which can impact population size) or waning immunity. As you continue your exploration, think about real infectious diseases that might be approximated by either one of the transmission types, and what approximate choices for the model parameters would describe those IDs."
nrec = 1 # number of items to record
out_records = c("Nothing")
out_types = c("None")
out_notes = c("")
outcomes = data.frame( TaskID = rep(tid,nrec),
                       TaskText = rep(tasktext,nrec),
                      RecordID = paste0('T',tid,'R',(1:nrec)),
                      Record = out_records, 
                      Type = out_types, 
                      Note = out_notes)
alloutcomes = rbind(alloutcomes,outcomes)
rc = rc + nrec #increment record counter by number of outcomes to record for this task 
#save the fully filled task table to a tsv file
alloutcomes$QuizID = paste0(packagename,"_",appsettings$appid)
alloutcomes$AppTitle = appsettings$apptitle
alloutcomes$AppID = appsettings$appid
#remove a few variables from the data frame
savedoutcomes <- dplyr::select(alloutcomes,QuizID,AppID,AppTitle,TaskID,TaskText,RecordID,Record,Type,Note)     
write.table(savedoutcomes, paste0(appsettings$appid,"_tasktable.tsv"), append = FALSE, sep = "\t", row.names = F, col.names = TRUE)
# Take all the text stored in the table and print the tasks and items to record
write_tasktext(alloutcomes)

Further Information {#shinytab4}

References



Try the DSAIDE package in your browser

Any scripts or data that you put into this service are public.

DSAIDE documentation built on Aug. 24, 2023, 1:07 a.m.