Title: | Effective Reproduction Number Estimation |
---|---|
Description: | Estimate the effective reproduction number from wastewater and clinical data sources. |
Authors: | David Champredon [aut, cre] , Warsame Yusuf [aut] , Irena Papst [aut] |
Maintainer: | David Champredon <[email protected]> |
License: | MIT + file LICENSE |
Version: | 2.0.0 |
Built: | 2024-10-31 20:38:55 UTC |
Source: | CRAN |
Infer daily counts from aggregates
agg_to_daily(cl.data, dist.gi, prm.daily, silent = FALSE)
agg_to_daily(cl.data, dist.gi, prm.daily, silent = FALSE)
cl.data |
Data frame. Must have variables:
|
dist.gi |
List. Parameters for the generation interval distribution in the same format as returned by |
prm.daily |
List. Parameters for daily report inference via MCMC. Elements include:
|
silent |
Logical. Flag to suppress all output messages, warnings, and progress bars. |
A list containing a data frame with individual realizations of daily reported cases and the JAGS object.
# Importing data attached to the `ern` package # and selecting the Omicron wave in Ontario, Canada. # This is *weekly* incidence. data(cl.data) data = cl.data[cl.data$pt == 'on' & cl.data$date > as.Date('2021-11-30') & cl.data$date < as.Date('2021-12-31'),] head(data) dist.gi = ern::def_dist( dist = "gamma", mean = 6.84, mean_sd = 0.7486, shape = 2.39, shape_sd = 0.3573, max = 15 ) a = agg_to_daily( cl.data = data, dist.gi = dist.gi, prm.daily = list( method = "renewal", popsize = 14e6, # MCMC parameters. # small values for computation speed for this example. # Increase for better accuracy burn = 100, iter = 100, chains = 2, # - - - - - prior_R0_shape = 2, prior_R0_rate = 0.6, prior_alpha_shape = 1, prior_alpha_rate = 1 )) # This is a Bayesian inference, so we # have a posterior distribution of # daily incidences. Here we just plot # one single draw: df = a$df df1 = df[df$id==1,] plot(x = df1$t, y = df1$value, typ = 'o', xlab = 'days', ylab = 'daily incidence', main = 'Posterior daily incidence infered from weekly incidence') # Extract of the parameters values from the first chain a$jags.object[[1]][1:9,1:9]
# Importing data attached to the `ern` package # and selecting the Omicron wave in Ontario, Canada. # This is *weekly* incidence. data(cl.data) data = cl.data[cl.data$pt == 'on' & cl.data$date > as.Date('2021-11-30') & cl.data$date < as.Date('2021-12-31'),] head(data) dist.gi = ern::def_dist( dist = "gamma", mean = 6.84, mean_sd = 0.7486, shape = 2.39, shape_sd = 0.3573, max = 15 ) a = agg_to_daily( cl.data = data, dist.gi = dist.gi, prm.daily = list( method = "renewal", popsize = 14e6, # MCMC parameters. # small values for computation speed for this example. # Increase for better accuracy burn = 100, iter = 100, chains = 2, # - - - - - prior_R0_shape = 2, prior_R0_rate = 0.6, prior_alpha_shape = 1, prior_alpha_rate = 1 )) # This is a Bayesian inference, so we # have a posterior distribution of # daily incidences. Here we just plot # one single draw: df = a$df df1 = df[df$id==1,] plot(x = df1$t, y = df1$value, typ = 'o', xlab = 'days', ylab = 'daily incidence', main = 'Posterior daily incidence infered from weekly incidence') # Extract of the parameters values from the first chain a$jags.object[[1]][1:9,1:9]
A subset of COVID-19 weekly reports in the Government of Canada Health Infobase. See https://health-infobase.canada.ca/covid-19/
cl.data
cl.data
cl.data
A data frame with 96 rows and 3 columns:
pt
: standard two-character abbreviation (lowercase)
of the province name (based on Statistics Canada 2021 census abbreviations)
date
: report date
value
: count of reported cases for the previous week
Filter indicating a specific province to extract a sample dataset for use with estimate_R_cl()
, e.g.
estimate_R_cl(cl.data = dplyr::filter(cl.data, pt == 'bc'), ...)
Define a family of distributions.
def_dist(dist, ...)
def_dist(dist, ...)
dist |
distribution type. Distributions currently supported are:
|
... |
a series of distribution parameters. Included should be the following:
|
List with components specified in the parameters.
d = def_dist( dist = "gamma", mean = 3.49, mean_sd = 0.1477, shape = 8.5, shape_sd = 1.8945, max = 8 ) print(d)
d = def_dist( dist = "gamma", mean = 3.49, mean_sd = 0.1477, shape = 8.5, shape_sd = 1.8945, max = 8 ) print(d)
Estimate the effective reproduction from clinical report data
estimate_R_cl( cl.data, dist.repdelay, dist.repfrac, dist.incub, dist.gi, prm.daily = list(method = "linear", popsize = NULL, burn = 500, iter = 2000, chains = 3, prior_R0_shape = 2, prior_R0_rate = 0.6, prior_alpha_shape = 1, prior_alpha_rate = 1, first.agg.period = NULL), prm.daily.check = list(agg.reldiff.tol = 10), prm.smooth = list(method = "rollmean", align = "right", window = 7), prm.R = list(iter = 10, CI = 0.95, window = 7, config.EpiEstim = NULL), RL.max.iter = 10, silent = FALSE )
estimate_R_cl( cl.data, dist.repdelay, dist.repfrac, dist.incub, dist.gi, prm.daily = list(method = "linear", popsize = NULL, burn = 500, iter = 2000, chains = 3, prior_R0_shape = 2, prior_R0_rate = 0.6, prior_alpha_shape = 1, prior_alpha_rate = 1, first.agg.period = NULL), prm.daily.check = list(agg.reldiff.tol = 10), prm.smooth = list(method = "rollmean", align = "right", window = 7), prm.R = list(iter = 10, CI = 0.95, window = 7, config.EpiEstim = NULL), RL.max.iter = 10, silent = FALSE )
cl.data |
Data frame. Must have variables:
|
dist.repdelay |
List. Parameters for the reporting delay distribution in the same format as returned by |
dist.repfrac |
List. Parameters for the reporting fraction distribution in the same format as returned by |
dist.incub |
List. Parameters for the incubation period distribution in the same format as returned by |
dist.gi |
List. Parameters for the generation interval distribution in the same format as returned by |
prm.daily |
List. Parameters for daily report inference via MCMC. Elements include:
|
prm.daily.check |
List. Parameters for checking aggregated to daily report inference. Elements include:
Set this entire argument to |
prm.smooth |
List. list of smoothing parameters. Parameters should be specified as followed:
Set this entire list to |
prm.R |
List. Settings for the ensemble when calculating Rt. Elements include:
|
RL.max.iter |
Integer. Maximum of iterations for the Richardson-Lucy deconvolution algorithm. |
silent |
Logical. Flag to suppress all output messages, warnings, and progress bars. |
List. Elements include:
cl.data
: original aggregated reports signal
cl.daily
: reports as input for Rt calculation (inferred daily counts, smoothed)
inferred.agg
: inferred daily reports aggregated on the reporting schedule as input in cl.data
R
: the effective R estimate (summary from ensemble)
plot_diagnostic_cl()
estimate_R_ww()
# -- THIS EXAMPLE TAKES ABOUT 30 SECONDS TO RUN -- # Estimate Rt ## Not run: # Load SARS-CoV-2 reported cases in Quebec # during the Summer 2021 dat <- (ern::cl.data |> dplyr::filter( pt == "qc", dplyr::between(date, as.Date("2021-06-01"), as.Date("2021-09-01")) ) ) # distributions dist.repdelay = ern::def_dist( dist = 'gamma', mean = 5, mean_sd = 1, sd = 1, sd_sd = 0.1, max = 10 ) dist.repfrac = ern::def_dist( dist = "unif", min = 0.1, max = 0.3 ) dist.incub = ern::def_dist( dist = "gamma", mean = 3.49, mean_sd = 0.1477, shape = 8.5, shape_sd = 1.8945, max = 8 ) dist.gi = ern::def_dist( dist = "gamma", mean = 6, mean_sd = 0.75, shape = 2.4, shape_sd = 0.3, max = 10 ) # settings prm.daily <- list( method = "renewal", popsize = 8.5e6, # Q3 (July 1) 2022 estimate for Quebec burn = 500, iter = 500, chains = 2, prior_R0_shape = 1.1, prior_R0_rate = 0.6, prior_alpha_shape = 1, prior_alpha_rate = 1 ) prm.daily.check <- list( agg.reldiff.tol = 10 ) prm.smooth <- list( method = "rollmean", align = "center", window = 7 ) prm.R <- list( iter = 20, CI = 0.95, window = 7, config.EpiEstim = NULL ) x <- estimate_R_cl( dat, dist.repdelay, dist.repfrac, dist.incub, dist.gi, prm.daily, prm.daily.check, prm.smooth, prm.R ) # Rt estimates print(x$R) ## End(Not run)
# -- THIS EXAMPLE TAKES ABOUT 30 SECONDS TO RUN -- # Estimate Rt ## Not run: # Load SARS-CoV-2 reported cases in Quebec # during the Summer 2021 dat <- (ern::cl.data |> dplyr::filter( pt == "qc", dplyr::between(date, as.Date("2021-06-01"), as.Date("2021-09-01")) ) ) # distributions dist.repdelay = ern::def_dist( dist = 'gamma', mean = 5, mean_sd = 1, sd = 1, sd_sd = 0.1, max = 10 ) dist.repfrac = ern::def_dist( dist = "unif", min = 0.1, max = 0.3 ) dist.incub = ern::def_dist( dist = "gamma", mean = 3.49, mean_sd = 0.1477, shape = 8.5, shape_sd = 1.8945, max = 8 ) dist.gi = ern::def_dist( dist = "gamma", mean = 6, mean_sd = 0.75, shape = 2.4, shape_sd = 0.3, max = 10 ) # settings prm.daily <- list( method = "renewal", popsize = 8.5e6, # Q3 (July 1) 2022 estimate for Quebec burn = 500, iter = 500, chains = 2, prior_R0_shape = 1.1, prior_R0_rate = 0.6, prior_alpha_shape = 1, prior_alpha_rate = 1 ) prm.daily.check <- list( agg.reldiff.tol = 10 ) prm.smooth <- list( method = "rollmean", align = "center", window = 7 ) prm.R <- list( iter = 20, CI = 0.95, window = 7, config.EpiEstim = NULL ) x <- estimate_R_cl( dat, dist.repdelay, dist.repfrac, dist.incub, dist.gi, prm.daily, prm.daily.check, prm.smooth, prm.R ) # Rt estimates print(x$R) ## End(Not run)
Estimate the effective reproduction from wastewater concentration data.
estimate_R_ww( ww.conc, dist.fec, dist.gi, scaling.factor = 1, prm.smooth = list(window = 14, align = "center", method = "loess", span = 0.2), prm.R = list(iter = 10, CI = 0.95, window = 7, config.EpiEstim = NULL), silent = FALSE, RL.max.iter = 9 )
estimate_R_ww( ww.conc, dist.fec, dist.gi, scaling.factor = 1, prm.smooth = list(window = 14, align = "center", method = "loess", span = 0.2), prm.R = list(iter = 10, CI = 0.95, window = 7, config.EpiEstim = NULL), silent = FALSE, RL.max.iter = 9 )
ww.conc |
Data frame. Must have variables:
|
dist.fec |
List. Parameters for the fecal shedding distribution in the same format as returned by |
dist.gi |
List. Parameters for the generation interval distribution in the same format as returned by |
scaling.factor |
Numeric. Scaling from wastewater concentration to prevalence. This value may be assumed or independently calibrated to data. |
prm.smooth |
List. list of smoothing parameters. Parameters should be specified as followed:
Set this entire list to |
prm.R |
List. Settings for the ensemble when calculating Rt. Elements include:
|
silent |
Logical. Flag to suppress all output messages, warnings, and progress bars. |
RL.max.iter |
Integer. Maximum of iterations for the Richardson-Lucy deconvolution algorithm. |
List. Elements include:
ww.conc
: original wastewater signal
ww.smooth
: smoothed wastewater signal
inc
: inferred incidence
R
: the effective reproduction number estimate
plot_diagnostic_ww()
estimate_R_cl()
# Load data of viral concentration in wastewater data("ww.data") # Run the estimation of Rt based on the wastewater data x = estimate_R_ww( ww.conc = ww.data, dist.fec = ern::def_dist( dist = "gamma", mean = 12.90215, mean_sd = 1.136829, shape = 1.759937, shape_sd = 0.2665988, max = 33 ), dist.gi = ern::def_dist( dist = "gamma", mean = 6.84, mean_sd = 0.7486, shape = 2.39, shape_sd = 0.3573, max = 15 ), silent = TRUE ) # Rt estimates head(x$R) # inferred daily incidence head(x$inc)
# Load data of viral concentration in wastewater data("ww.data") # Run the estimation of Rt based on the wastewater data x = estimate_R_ww( ww.conc = ww.data, dist.fec = ern::def_dist( dist = "gamma", mean = 12.90215, mean_sd = 1.136829, shape = 1.759937, shape_sd = 0.2665988, max = 33 ), dist.gi = ern::def_dist( dist = "gamma", mean = 6.84, mean_sd = 0.7486, shape = 2.39, shape_sd = 0.3573, max = 15 ), silent = TRUE ) # Rt estimates head(x$R) # inferred daily incidence head(x$inc)
Extract MCMC chains from a JAGS object
extract_mcmc_values(chain, jags.obj)
extract_mcmc_values(chain, jags.obj)
chain |
Integer. Chain number. |
jags.obj |
JAGS object as returned by |
A dataframe of the chain values for selected parameters.
Get a discretized, truncated version of a distribution
get_discrete_dist(params)
get_discrete_dist(params)
params |
distribution params (output of |
Numeric. Vector with discretized density.
# Define distributions fec = ern::def_dist( dist = "gamma", mean = 12.90215, mean_sd = 1.136829, shape = 1.759937, shape_sd = 0.2665988, max = 33 ) gi = ern::def_dist( dist = "gamma", mean = 6.84, mean_sd = 0.7486, shape = 2.39, shape_sd = 0.3573, max = 15 ) # Get their (discretized) densities d.fec = get_discrete_dist(fec) d.gi = get_discrete_dist(gi) print(d.fec) print(d.gi)
# Define distributions fec = ern::def_dist( dist = "gamma", mean = 12.90215, mean_sd = 1.136829, shape = 1.759937, shape_sd = 0.2665988, max = 33 ) gi = ern::def_dist( dist = "gamma", mean = 6.84, mean_sd = 0.7486, shape = 2.39, shape_sd = 0.3573, max = 15 ) # Get their (discretized) densities d.fec = get_discrete_dist(fec) d.gi = get_discrete_dist(gi) print(d.fec) print(d.gi)
Daily incidence from linear interpolation
linear_int_daily(cl.data)
linear_int_daily(cl.data)
cl.data |
Aggregated incidence. |
A dataframe of daily incidence
Diagnostic plot for R estimation from clinical report data
plot_diagnostic_cl(r.estim, caption = NULL, wrap.plots = TRUE)
plot_diagnostic_cl(r.estim, caption = NULL, wrap.plots = TRUE)
r.estim |
List. Output of |
caption |
String. Caption to be inserted in the plot.
Default is |
wrap.plots |
Logical. Wrap the plots together into a single ggplot object?
If |
Plots of the clinical data used, the inferred daily incidence and
Rt estimates. If wrap.plots = TRUE
(the default) will return
wrapped plots (with x-axis aligned to facilitate the comaprison)
in a single object,
else will return a list of separate ggplot objects.
A ggplot
object (or a list of ggplot objects
if wrap.plots = FALSE
).
# -- THIS EXAMPLE TAKES ABOUT 30 SECONDS TO RUN -- # Estimate Rt ## Not run: # Load SARS-CoV-2 reported cases in Quebec # during the Summer 2021 dat <- (ern::cl.data |> dplyr::filter( pt == "qc", dplyr::between(date, as.Date("2021-06-01"), as.Date("2021-09-01")) ) ) # distributions dist.repdelay = ern::def_dist( dist = 'gamma', mean = 5, mean_sd = 1, sd = 1, sd_sd = 0.1, max = 10 ) dist.repfrac = ern::def_dist( dist = "unif", min = 0.1, max = 0.3 ) dist.incub = ern::def_dist( dist = "gamma", mean = 3.49, mean_sd = 0.1477, shape = 8.5, shape_sd = 1.8945, max = 8 ) dist.gi = ern::def_dist( dist = "gamma", mean = 6, mean_sd = 0.75, shape = 2.4, shape_sd = 0.3, max = 10 ) # settings prm.daily <- list( method = "renewal", popsize = 8.5e6, # Q3 (July 1) 2022 estimate for Quebec burn = 500, iter = 500, chains = 2, prior_R0_shape = 1.1, prior_R0_rate = 0.6, prior_alpha_shape = 1, prior_alpha_rate = 1 ) prm.daily.check <- list( agg.reldiff.tol = 10 ) prm.smooth <- list( method = "rollmean", align = "center", window = 7 ) prm.R <- list( iter = 20, CI = 0.95, window = 7, config.EpiEstim = NULL ) x <- estimate_R_cl( dat, dist.repdelay, dist.repfrac, dist.incub, dist.gi, prm.daily, prm.daily.check, prm.smooth, prm.R ) # Diagnostic plot for Rt estimates # from clinical data g = plot_diagnostic_cl(x) plot(g) g2 = plot_diagnostic_cl(x, caption = 'This is your caption', wrap.plots = FALSE) plot(g2$clinical_data) plot(g2$inferred_incidence) plot(g2$Rt) ## End(Not run)
# -- THIS EXAMPLE TAKES ABOUT 30 SECONDS TO RUN -- # Estimate Rt ## Not run: # Load SARS-CoV-2 reported cases in Quebec # during the Summer 2021 dat <- (ern::cl.data |> dplyr::filter( pt == "qc", dplyr::between(date, as.Date("2021-06-01"), as.Date("2021-09-01")) ) ) # distributions dist.repdelay = ern::def_dist( dist = 'gamma', mean = 5, mean_sd = 1, sd = 1, sd_sd = 0.1, max = 10 ) dist.repfrac = ern::def_dist( dist = "unif", min = 0.1, max = 0.3 ) dist.incub = ern::def_dist( dist = "gamma", mean = 3.49, mean_sd = 0.1477, shape = 8.5, shape_sd = 1.8945, max = 8 ) dist.gi = ern::def_dist( dist = "gamma", mean = 6, mean_sd = 0.75, shape = 2.4, shape_sd = 0.3, max = 10 ) # settings prm.daily <- list( method = "renewal", popsize = 8.5e6, # Q3 (July 1) 2022 estimate for Quebec burn = 500, iter = 500, chains = 2, prior_R0_shape = 1.1, prior_R0_rate = 0.6, prior_alpha_shape = 1, prior_alpha_rate = 1 ) prm.daily.check <- list( agg.reldiff.tol = 10 ) prm.smooth <- list( method = "rollmean", align = "center", window = 7 ) prm.R <- list( iter = 20, CI = 0.95, window = 7, config.EpiEstim = NULL ) x <- estimate_R_cl( dat, dist.repdelay, dist.repfrac, dist.incub, dist.gi, prm.daily, prm.daily.check, prm.smooth, prm.R ) # Diagnostic plot for Rt estimates # from clinical data g = plot_diagnostic_cl(x) plot(g) g2 = plot_diagnostic_cl(x, caption = 'This is your caption', wrap.plots = FALSE) plot(g2$clinical_data) plot(g2$inferred_incidence) plot(g2$Rt) ## End(Not run)
Diagnostic plot for R estimation from wastewater data
plot_diagnostic_ww(r.estim, caption = NULL, wrap.plots = TRUE)
plot_diagnostic_ww(r.estim, caption = NULL, wrap.plots = TRUE)
r.estim |
List. Output of |
caption |
Character. Optional plot caption. |
wrap.plots |
Logical.
Wrap all diagnostic plots into one single ggplot object (default = |
A ggplot
object.
estimate_R_ww()
plot_diagnostic_cl()
# Load data of viral concentration in wastewater data("ww.data") # Estimate Rt based on wastewater data x = estimate_R_ww( ww.conc = ww.data, dist.fec = ern::def_dist( dist = "gamma", mean = 12.9, mean_sd = 1.13, shape = 1.75, shape_sd = 0.26, max = 33 ), dist.gi = ern::def_dist( dist = "gamma", mean = 6.84, mean_sd = 0.74, shape = 2.39, shape_sd = 0.35, max = 15 ), silent = TRUE ) # Diagnostic plot g = plot_diagnostic_ww(x) plot(g) g2 = plot_diagnostic_ww(x, wrap.plots = FALSE, caption = "This is your caption") plot(g2$wastewater_data) plot(g2$inferred_incidence) plot(g2$Rt)
# Load data of viral concentration in wastewater data("ww.data") # Estimate Rt based on wastewater data x = estimate_R_ww( ww.conc = ww.data, dist.fec = ern::def_dist( dist = "gamma", mean = 12.9, mean_sd = 1.13, shape = 1.75, shape_sd = 0.26, max = 33 ), dist.gi = ern::def_dist( dist = "gamma", mean = 6.84, mean_sd = 0.74, shape = 2.39, shape_sd = 0.35, max = 15 ), silent = TRUE ) # Diagnostic plot g = plot_diagnostic_ww(x) plot(g) g2 = plot_diagnostic_ww(x, wrap.plots = FALSE, caption = "This is your caption") plot(g2$wastewater_data) plot(g2$inferred_incidence) plot(g2$Rt)
Plot a distribution
plot_dist(d)
plot_dist(d)
d |
List that defines the distribution (as returned by |
A ggplot object.
# Define a `ern` distribution: gi = ern::def_dist( dist = "gamma", mean = 6.84, mean_sd = 0.7486, shape = 2.39, shape_sd = 0.3573, max = 15 ) # Plot can be customized like any `ggplot` object: g = plot_dist(gi) + ggplot2::labs(subtitle = 'your subtitle') plot(g)
# Define a `ern` distribution: gi = ern::def_dist( dist = "gamma", mean = 6.84, mean_sd = 0.7486, shape = 2.39, shape_sd = 0.3573, max = 15 ) # Plot can be customized like any `ggplot` object: g = plot_dist(gi) + ggplot2::labs(subtitle = 'your subtitle') plot(g)
Plot the Gelman Rubin statistic for all parameters.
plot_gelman_rubin(jags.obj)
plot_gelman_rubin(jags.obj)
jags.obj |
JAGS object as returned by |
A ggplot
plot.
Plot MCMC traces
plot_traces(jags.obj)
plot_traces(jags.obj)
jags.obj |
JAGS object as returned by |
A ggplot
plot.
A subset of SARS-CoV-2 (N2 gene) concentration data in wastewater sampled from the Iona Island wastewater treatment plant in Vancouver between 7 July 2023 and 5 November 2023. Units are in N2 gene copies per milliliter of wastewater. Concentration was measured using RT-qPCR assays; RNA was extracted from suspended solids. See https://health-infobase.canada.ca/covid-19/wastewater/
ww.data
ww.data
ww.data
A data frame with 47 rows and 3 columns:
date
: sampling date
value
: mean sample concentration between multiple replicates