---
title: "Ready reckoner for Reff"
output:
bookdown::html_vignette2:
fig_caption: yes
code_folding: show
vignette: >
%\VignetteIndexEntry{Ready reckoner for Reff}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---
```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>"
)
```
```{r setup}
library(finalsize)
library(dplyr)
library(tidyr)
library(ggplot2)
```
The _finalsize_ package provides a quick way to calculate the effective reproduction number using the `r_eff()` function.
This vignette shows how to use the `contact_scaling` argument to calculate the effective reproduction number for different scenarios.
## Setup
We access social contacts data for the U.K. for six age groups: three school-age groups of 0 -- 4, 5 -- 11, 12 -- 17, and three adult groups of 18 -- 39, 40 -- 65, and 65+.
Age groups are chosen to model the effect of school closures and resulting reduction in social contacts for school-age groups on $R_\text{eff}$.
We assume all age groups are completely susceptible to infection.
```{r}
polymod <- socialmixr::polymod
contact_data <- socialmixr::contact_matrix(
polymod,
countries = "United Kingdom",
age.limits = c(0, 5, 12, 17, 40, 65),
symmetric = TRUE
)
# get the contact matrix and demography data
contact_matrix <- t(contact_data$matrix)
demography_vector <- contact_data$demography$population
# scale the contact matrix so the largest eigenvalue is 1.0
# this is to ensure that the overall epidemic dynamics correctly reflect
# the assumed value of R0
contact_matrix <- contact_matrix / max(Re(eigen(contact_matrix)$values))
# divide each row of the contact matrix by the corresponding demography
# this reflects the assumption that each individual in group {j} make contacts
# at random with individuals in group {i}
contact_matrix <- contact_matrix / demography_vector
n_demo_grps <- length(demography_vector)
# all individuals are equally and highly susceptible
n_susc_groups <- 1L
susc_guess <- 1.0
susc_uniform <- matrix(
data = susc_guess,
nrow = n_demo_grps,
ncol = n_susc_groups
)
p_susc_uniform <- matrix(
data = 1.0,
nrow = n_demo_grps,
ncol = n_susc_groups
)
```
## Scenarios of contact reduction
We model four scenarios of school closures, and multiple levels of scaling of adult social contacts.
Note that all values and assumptions are solely illustrative.
```{r}
# create an age-specific scaling vector for re-use
scaling_factor <- rep(1, n_demo_grps)
# adult age groups
i_adult <- c(4, 5, 6)
n_school_age <- 3L
```
We assume that:
1. Full school closures reduce all school-age groups' contacts by 80%;
2. 0-5 year olds' contacts are not affected in any other scenario;
3. When 50% of 5-11 year olds are at school, contacts are reduced by 40%;
4. 12-17 year olds have an 80% reduction in contacts except when all schools are open;
5. Adults' social contacts are not affected by school closures.
```{r}
# create scenarios of school closures
scenarios <- factor(
c("schools_closed", "ps_half_open", "ps_open", "schools_open"),
levels = c("schools_closed", "ps_half_open", "ps_open", "schools_open")
)
scenario_names <- c(
"Schools closed", "Primary schools 50% open",
"Primary schools open", "Schools open"
)
school_scaling <- list(
schools_closed = rep(0.2, n_school_age), # full closure cuts contacts by 80%
ps_half_open = c(1.0, 0.6, 0.2), # 50% 5-11 yr olds cuts contacts by 40%
ps_open = c(1.0, 1.0, 0.2),
schools_open = rep(1.0, n_school_age)
)
# make a tibble and cross-join with scaling values
scenarios <- tibble(
scenarios,
school_scaling
)
scaling_values <- seq(0.0, 1.0, 0.1) # adult scaling from 0% - 100%
scenarios <- crossing(
scenarios, scaling_values
)
```
```{r}
# combine adult and school-age contact scaling values for 4 * 11 scenarios
scenarios <- mutate(
scenarios,
contact_scaling = Map(
school_scaling, scaling_values,
f = function(x, y) {
scaling_factor <- c(x, rep(y, 3)) # all adult contacts scaled the same
}
)
)
# calculate R_eff assuming R0 = 3.0
r0 <- 3.0
scenarios <- mutate(
scenarios,
r_eff = vapply(
contact_scaling,
function(x) {
r_eff(
r0,
contact_matrix, demography_vector, susc_uniform,
p_susc_uniform,
contact_scaling = x
)
}, numeric(1)
)
)
```
We plot the $R_\text{eff}$ values.
```{r class.source = 'fold-hide'}
ggplot(scenarios) +
geom_line(
aes(scaling_values, r_eff, col = scenarios)
) +
scale_color_brewer(
palette = "Dark2",
labels = scenario_names
) +
scale_x_continuous(
labels = scales::percent
) +
scale_y_continuous(
breaks = seq(0.5, 3, 0.5)
) +
theme_bw() +
labs(
x = "% of adult contacts",
y = "Reff",
colour = NULL
) +
theme(
axis.title.y.left = ggtext::element_markdown(),
legend.position = "top"
)
```