Skip to content

Commit 92e1878

Browse files
committed
add compilation of edits
- create baseline model section - change object names when using socialmixr - expand the initial conditions vector code - create matrix with simpler code - print internvetion class objects - reduce one level to subtitles of interventions - expand binding of data frame when comparing all internvetions
1 parent 0af4566 commit 92e1878

1 file changed

Lines changed: 78 additions & 56 deletions

File tree

episodes/modelling-interventions.Rmd

Lines changed: 78 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
title: 'Modelling interventions'
33
teaching: 45 # teaching time in minutes
44
exercises: 30 # exercise time in minutes
5-
65
---
76

87
```{r setup, echo= FALSE, message = FALSE, warning = FALSE}
@@ -53,58 +52,93 @@ In this tutorial different types of intervention and how they can be modelled ar
5352

5453
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
5554

56-
## Non-pharmaceutical interventions
55+
## A baseline model
5756

58-
[Non-pharmaceutical interventions](../learners/reference.md#NPIs) (NPIs) are measures put in place to reduce transmission that do not include the administration of drugs or vaccinations. NPIs aim at reducing contacts between infectious and susceptible individuals by closure of schools and workplaces, and other measures to prevent the spread of the disease, for example, washing hands and wearing masks.
57+
We will investigate the effect of interventions on a COVID-19 outbreak using an SEIR model (`model_default()` in the R package `{epidemics}`). To be able to see the effect of our intervention, we will run a baseline variant of the model, i.e, without intervention.
5958

60-
We will investigate the effect of interventions on a COVID-19 outbreak using an SEIR model (`model_default()` in the R package `{epidemics}`). The SEIR model divides the population into four compartments: Susceptible (S), Exposed (E), Infectious (I), and Recovered (R). We will set the following parameters for our model: $R_0 = 2.7$ (basic reproduction number), latent period or pre-infectious period $= 4$ days, and the infectious period $= 5.5$ days (parameters adapted from [Davies et al. (2020)](https://doi.org/10.1016/S2468-2667(20)30133-X)). We adopt a contact matrix with age bins 0-18, 18-65, 65 years and older using `{socialmixr}`, and assume that one in every 1 million individuals in each age group is infectious at the start of the epidemic.
59+
The SEIR model divides the population into four compartments: Susceptible (S), Exposed (E), Infectious (I), and Recovered (R). We will set the following parameters for our model: $R_0 = 2.7$ (basic reproduction number), latent period or pre-infectious period $= 4$ days, and the infectious period $= 5.5$ days (parameters adapted from [Davies et al. (2020)](https://doi.org/10.1016/S2468-2667(20)30133-X)). We adopt a contact matrix with age bins 0-18, 18-65, 65 years and older using `{socialmixr}`, and assume that one in every 1 million individuals in each age group is infectious at the start of the epidemic.
6160

6261
```{r model_setup, echo = TRUE, message = FALSE}
63-
polymod <- socialmixr::polymod
64-
contact_data <- socialmixr::contact_matrix(
65-
polymod,
62+
# load survey data
63+
survey_data <- socialmixr::polymod
64+
65+
# generate contact matrix
66+
cm_results <- socialmixr::contact_matrix(
67+
survey = survey_data,
6668
countries = "United Kingdom",
6769
age.limits = c(0, 15, 65),
6870
symmetric = TRUE
6971
)
7072
71-
# prepare contact matrix
72-
contact_matrix <- t(contact_data$matrix)
73+
# transpose contact matrix
74+
cm_matrix <- t(cm_results$matrix)
7375
7476
# prepare the demography vector
75-
demography_vector <- contact_data$demography$population
76-
names(demography_vector) <- rownames(contact_matrix)
77+
demography_vector <- cm_results$demography$population
78+
names(demography_vector) <- rownames(cm_matrix)
7779
7880
# initial conditions: one in every 1 million is infected
7981
initial_i <- 1e-6
8082
initial_conditions <- c(
81-
S = 1 - initial_i, E = 0, I = initial_i, R = 0, V = 0
83+
S = 1 - initial_i,
84+
E = 0,
85+
I = initial_i,
86+
R = 0,
87+
V = 0
8288
)
8389
8490
# build for all age groups
85-
initial_conditions <- matrix(
86-
rep(initial_conditions, dim(contact_matrix)[1]),
87-
ncol = 5, byrow = TRUE
91+
initial_conditions <- base::rbind(
92+
initial_conditions,
93+
initial_conditions,
94+
initial_conditions
8895
)
89-
rownames(initial_conditions) <- rownames(contact_matrix)
96+
rownames(initial_conditions) <- rownames(cm_matrix)
9097
9198
# prepare the population to model as affected by the epidemic
9299
uk_population <- epidemics::population(
93100
name = "UK",
94-
contact_matrix = contact_matrix,
101+
contact_matrix = cm_matrix,
95102
demography_vector = demography_vector,
96103
initial_conditions = initial_conditions
97104
)
98105
```
99106

100-
#### Effect of school closures on COVID-19 spread
107+
We run the model with a transmission rate $= 2.7/5.5$ (remember that [transmission rate = $R_0$* recovery rate](../episodes/simulating-transmission.md#the-basic-reproduction-number-r_0)), infectiousness rate $1/= 4$ and the recovery rate $= 1/5.5$ as follows:
108+
109+
```{r, echo = TRUE, message = FALSE}
110+
# time periods
111+
preinfectious_period <- 4.0
112+
infectious_period <- 5.5
113+
basic_reproduction <- 2.7
114+
115+
# rates
116+
infectiousness_rate <- 1.0 / preinfectious_period
117+
recovery_rate <- 1.0 / infectious_period
118+
transmission_rate <- basic_reproduction * recovery_rate
119+
120+
# run baseline simulation with no intervention
121+
output_baseline <- model_default(
122+
population = uk_population,
123+
transmission_rate = transmission_rate,
124+
infectiousness_rate = infectiousness_rate,
125+
recovery_rate = recovery_rate,
126+
time_end = 300, increment = 1.0
127+
)
128+
```
129+
130+
## Non-pharmaceutical interventions
131+
132+
[Non-pharmaceutical interventions](../learners/reference.md#NPIs) (NPIs) are measures put in place to reduce transmission that do not include the administration of drugs or vaccinations. NPIs aim at reducing contacts between infectious and susceptible individuals by closure of schools and workplaces, and other measures to prevent the spread of the disease, for example, washing hands and wearing masks.
133+
134+
### Effect of school closures on COVID-19 spread
101135

102136
The first NPI we will consider is the effect of school closures on reducing the number of individuals infected with COVID-19 over time. We assume that a school closure will reduce the frequency of contacts within and between different age groups. Based on empirical studies, we assume that school closures will reduce the contacts between school-aged children (aged 0-15) by 50%, and will cause a small reduction (1%) in the contacts between adults (aged 15 and over).
103137

104138
To include an intervention in our model we must create an `intervention` object. The inputs are the name of the intervention (`name`), the type of intervention (`contacts` or `rate`), the start time (`time_begin`), the end time (`time_end`) and the reduction (`reduction`). The values of the reduction matrix are specified in the same order as the age groups in the contact matrix.
105139

106140
```{r}
107-
rownames(contact_matrix)
141+
rownames(cm_matrix)
108142
```
109143

110144
Therefore, we specify ` reduction = matrix(c(0.5, 0.01, 0.01))`. We assume that the school closures start on day 50 and continue to be in place for a further 100 days. Therefore our intervention object is:
@@ -117,6 +151,8 @@ close_schools <- intervention(
117151
time_end = 50 + 100,
118152
reduction = matrix(c(0.5, 0.01, 0.01))
119153
)
154+
155+
close_schools
120156
```
121157

122158
::::::::::::::::::::::::::::::::::::: callout
@@ -126,38 +162,25 @@ In `{epidemics}`, the contact matrix is scaled down by proportions for the perio
126162

127163
```{r echo = FALSE}
128164
reduction <- matrix(c(0.5, 0.1))
129-
contact_matrix_example <- matrix(c(1, 1, 1, 1), nrow = 2)
130-
contact_matrix_example
165+
cm_matrix_example <- matrix(c(1, 1, 1, 1), nrow = 2)
166+
cm_matrix_example
131167
```
132168

133169
If the reduction is 50% in group 1 and 10% in group 2, the contact matrix during the intervention will be:
134170

135171
```{r echo = FALSE}
136-
contact_matrix_example[1, ] <- contact_matrix_example[1, ] * (1 - reduction[1])
137-
contact_matrix_example[, 1] <- contact_matrix_example[, 1] * (1 - reduction[1])
138-
contact_matrix_example[2, ] <- contact_matrix_example[2, ] * (1 - reduction[2])
139-
contact_matrix_example[, 2] <- contact_matrix_example[, 2] * (1 - reduction[2])
140-
contact_matrix_example
172+
cm_matrix_example[1, ] <- cm_matrix_example[1, ] * (1 - reduction[1])
173+
cm_matrix_example[, 1] <- cm_matrix_example[, 1] * (1 - reduction[1])
174+
cm_matrix_example[2, ] <- cm_matrix_example[2, ] * (1 - reduction[2])
175+
cm_matrix_example[, 2] <- cm_matrix_example[, 2] * (1 - reduction[2])
176+
cm_matrix_example
141177
```
142178

143179
The contacts within group 1 are reduced by 50% twice to accommodate for a 50% reduction in outgoing and incoming contacts ($1\times 0.5 \times 0.5 = 0.25$). Similarly, the contacts within group 2 are reduced by 10% twice. The contacts between group 1 and group 2 are reduced by 50% and then by 10% ($1 \times 0.5 \times 0.9= 0.45$).
144180

145181
::::::::::::::::::::::::::::::::::::::::::::::::
146182

147-
Using transmission rate $= 2.7/5.5$ (remember that [transmission rate = $R_0$/ infectious period](../episodes/simulating-transmission.md#the-basic-reproduction-number-r_0)), infectiousness rate $1/= 4$ and the recovery rate $= 1/5.5$ we run the model with ` intervention = list(contacts = close_schools)` as follows:
148-
149-
```{r}
150-
# time periods
151-
preinfectious_period <- 4.0
152-
infectious_period <- 5.5
153-
basic_reproduction <- 2.7
154-
155-
# rates
156-
infectiousness_rate <- 1.0 / preinfectious_period
157-
recovery_rate <- 1.0 / infectious_period
158-
transmission_rate <- basic_reproduction / infectious_period
159-
```
160-
183+
We run the model with ` intervention = list(contacts = close_schools)` as follows:
161184

162185
```{r school}
163186
output_school <- model_default(
@@ -175,25 +198,14 @@ output_school <- model_default(
175198
```
176199

177200

178-
To be able to see the effect of our intervention, we also run a baseline variant of the model, i.e, without intervention, combine the two outputs into one data frame, and then plot the output. Here we plot the total number of infectious individuals in all age groups using `ggplot2::stat_summary()` function:
201+
To observe the effect of our intervention, we will combine the baseline and intervention outputs into a single data frame and then plot the results. Here we plot the total number of infectious individuals in all age groups using `ggplot2::stat_summary()` function:
179202

180203
```{r baseline, echo = TRUE, fig.width = 10}
181-
# run baseline simulation with no intervention
182-
output_baseline <- model_default(
183-
population = uk_population,
184-
transmission_rate = transmission_rate,
185-
infectiousness_rate = infectiousness_rate,
186-
recovery_rate = recovery_rate,
187-
time_end = 300, increment = 1.0
188-
)
189-
190204
# create intervention_type column for plotting
191205
output_school$intervention_type <- "school closure"
192206
output_baseline$intervention_type <- "baseline"
193207
output <- rbind(output_school, output_baseline)
194208
195-
library(tidyverse)
196-
197209
output %>%
198210
filter(compartment == "infectious") %>%
199211
ggplot() +
@@ -224,11 +236,12 @@ output %>%
224236
y = "Individuals"
225237
)
226238
```
239+
227240
We can see that with the intervention in place, the infection still spreads through the population and hence accumulation of immunity contributes to the eventual peak-and-decline. However, the peak number of infectious individuals is smaller (green dashed line) than the baseline with no intervention in place (red solid line), showing a reduction in the absolute number of cases.
228241

229242

230243

231-
#### Effect of mask wearing on COVID-19 spread
244+
### Effect of mask wearing on COVID-19 spread
232245

233246
We can also model the effect of other NPIs by reducing the value of the relevant parameters. For example, investigating the effect of mask wearing on the number of individuals infected with COVID-19 over time.
234247

@@ -244,6 +257,8 @@ mask_mandate <- intervention(
244257
time_end = 40 + 200,
245258
reduction = 0.163
246259
)
260+
261+
mask_mandate
247262
```
248263

249264
To implement this intervention on the transmission rate $\beta$, we specify `intervention = list(transmission_rate = mask_mandate)`.
@@ -372,10 +387,12 @@ Here we will assume all age groups are vaccinated at the same rate 0.01 and that
372387
# prepare a vaccination object
373388
vaccinate <- vaccination(
374389
name = "vaccinate all",
375-
time_begin = matrix(40, nrow(contact_matrix)),
376-
time_end = matrix(40 + 150, nrow(contact_matrix)),
390+
time_begin = matrix(40, nrow(cm_matrix)),
391+
time_end = matrix(40 + 150, nrow(cm_matrix)),
377392
nu = matrix(c(0.01, 0.01, 0.01))
378393
)
394+
395+
vaccinate
379396
```
380397

381398
We pass our vaccination object into the model using the argument `vaccination = vaccinate`:
@@ -408,7 +425,12 @@ Plot the three interventions vaccination, school closure and mask mandate and th
408425
```{r plot_vaccinate, echo = TRUE, message = FALSE, fig.width = 10}
409426
# create intervention_type column for plotting
410427
output_vaccinate$intervention_type <- "vaccination"
411-
output <- rbind(output_school, output_masks, output_vaccinate, output_baseline)
428+
output <- rbind(
429+
output_school,
430+
output_masks,
431+
output_vaccinate,
432+
output_baseline
433+
)
412434
413435
output %>%
414436
filter(compartment == "infectious") %>%

0 commit comments

Comments
 (0)