| Type: | Package |
| Title: | Simulate and Evaluate Targeted Interventions in Infectious Disease Outbreaks |
| Version: | 1.0.0 |
| Description: | Branching process simulation model of infectious disease transmission with flexible parameterisation of epidemiology and targeted interventions, including isolation, contact tracing and quarantine, to reduce transmission, together with functions to evaluate outbreak control. Introduced in Hellewell et al. (2020) <doi:10.1016/S2214-109X(20)30074-7>. |
| License: | MIT + file LICENSE |
| URL: | https://epiforecasts.io/ringbp/, https://github.com/epiforecasts/ringbp |
| BugReports: | https://github.com/epiforecasts/ringbp/issues |
| Depends: | R (≥ 4.4.0) |
| Imports: | checkmate, data.table, sn |
| Suggests: | future, future.apply, knitr, rmarkdown, roxyglobals (≥ 1.0.0), spelling, testthat (≥ 3.0.0), tinyplot |
| VignetteBuilder: | knitr |
| Config/roxyglobals/filename: | globals.R |
| Config/roxyglobals/unique: | FALSE |
| Config/testthat/edition: | 3 |
| Encoding: | UTF-8 |
| Language: | en-GB |
| RoxygenNote: | 7.3.3 |
| NeedsCompilation: | no |
| Packaged: | 2026-06-07 21:12:12 UTC; lshjl15 |
| Author: | Joel Hellewell |
| Maintainer: | Joshua W. Lambert <joshua.lambert@lshtm.ac.uk> |
| Repository: | CRAN |
| Date/Publication: | 2026-06-15 13:30:02 UTC |
ringbp: Simulate and Evaluate Targeted Interventions in Infectious Disease Outbreaks
Description
Branching process simulation model of infectious disease transmission with flexible parameterisation of epidemiology and targeted interventions, including isolation, contact tracing and quarantine, to reduce transmission, together with functions to evaluate outbreak control. Introduced in Hellewell et al. (2020) doi:10.1016/S2214-109X(20)30074-7.
Author(s)
Maintainer: Joshua W. Lambert joshua.lambert@lshtm.ac.uk (ORCID)
Authors:
Joel Hellewell Joel.Hellewell@lshtm.ac.uk (ORCID)
Sam Abbott contact@samabbott.co.uk (ORCID)
Amy Gimma amy.gimma@lshtm.ac.uk
Tim Lucas tim.lucas@leicester.ac.uk
Sebastian Funk sebastian.funk@lshtm.ac.uk
Adam Kucharski adam.kucharski@lshtm.ac.uk
Carl A. B. Pearson carl.ab.pearson@gmail.com (ORCID) [reviewer]
Other contributors:
Hugo Gruson hugo.gruson@data.org (ORCID) [contributor]
See Also
Useful links:
Report bugs at https://github.com/epiforecasts/ringbp/issues
Coerce a probability input to a probability generating function.
Description
Coerce a probability input to a probability generating function.
Usage
as_prob_function(x)
Arguments
x |
An R object. |
Details
Used to create time-constant functions from numeric scalar inputs
in *_opts() functions so that users can provide simple number inputs
but the internal outbreak simulation can use time-varying functions that
generate probabilities.
This function also contains the input checking to ensure valid numeric
scalar probabilities or numeric generating functions are provided.
Functions input to as_prob_function() are input checked and then returned.
Value
A numeric generating function
Check a distribution function returns valid output and has the correct number of arguments
Description
Check a distribution function returns valid output and has the correct number of arguments
Usage
check_dist_func(
func,
dist_name,
n_req_args = 1,
func_eval_min = 0,
finite = TRUE
)
Arguments
func |
a function. |
dist_name |
a |
n_req_args |
a single |
func_eval_min |
a single |
finite |
Check for only finite values in distribution output, passed
to |
Value
TRUE if all the checks pass or an error is thrown if the
distribution function is invalid.
Cross-check *_opts() lists to run the ringbp model
Description
Cross-check *_opts() lists to run the ringbp model
Usage
cross_check_opts(delays, event_probs)
Arguments
delays |
a |
event_probs |
a |
Details
Currently the only cross-checking is between
onset_to_self_isolation from delay_opts() and
symptomatic_self_isolate from event_prob_opts().
If delays$onset_to_self_isolation carries a cross_checked attribute
set to TRUE, the checks are skipped and TRUE is returned immediately.
This lets scenario_sim() cross-check the options once and then tag
delays so that the per-replicate outbreak_model() calls do not
repeat the check (and re-emit its warning) for every simulation replicate.
The attribute is set on a local copy of delays (a single
scenario_sim() or outbreak_model()) call), and does not persist, so
the warning will be repeated in separate scenario_sim() or
outbreak_model()) calls.
Value
TRUE if all the checks pass or an error or warning is thrown if
the simulation options are incompatible.
Create a list of delay distributions to run the ringbp model
Description
Create a list of delay distributions to run the ringbp model
Usage
delay_opts(
incubation_period,
onset_to_isolation,
latent_period = 0,
onset_to_self_isolation = function(n) rep(Inf, n)
)
Arguments
incubation_period |
a |
onset_to_isolation |
a |
latent_period |
a non-negative If |
onset_to_self_isolation |
a By default |
Value
A list with class <ringbp_delay_opts>.
Examples
delay_opts(
incubation_period = \(n) rweibull(n = n, shape = 2.32, scale = 6.49),
onset_to_isolation = \(n) rweibull(n = n, shape = 1.65, scale = 4.28)
)
Create a list of event probabilities to run the ringbp model
Description
Create a list of event probabilities to run the ringbp model
Usage
event_prob_opts(
asymptomatic,
presymptomatic_transmission,
symptomatic_traced,
symptomatic_self_isolate = 0
)
Arguments
asymptomatic |
a |
presymptomatic_transmission |
a |
symptomatic_traced |
a A scalar is treated as a constant contact-tracing probability over the
whole simulation. A Only contacts whose infector is symptomatic are eligible for tracing
(see |
symptomatic_self_isolate |
a If |
Value
A list with class <ringbp_event_prob_opts>.
Examples
event_prob_opts(
asymptomatic = 0.1,
presymptomatic_transmission = 0.5,
symptomatic_traced = 0.2
)
# time-varying contact tracing ascertainment: programme activates
# on day 30 and ascertains 50%
event_prob_opts(
asymptomatic = 0.1,
presymptomatic_transmission = 0.5,
symptomatic_traced = \(t) ifelse(t < 30, 0, 0.5)
)
Outbreak extinction functions
Description
extinct_prob(): Calculate proportion of runs that have controlled outbreak
detect_extinct(): Calculate whether outbreaks went extinct or not
Usage
extinct_prob(scenario, extinction_week = NULL)
detect_extinct(scenario, extinction_week = NULL)
Arguments
scenario |
a |
extinction_week |
By default
If extinction occurs before the |
Details
The data passed to scenario has to be produced by scenario_sim().
It cannot be produced by outbreak_model() as it requires the sim column,
which is only appended in scenario_sim().
Warning: the output from scenario_sim() contains an cap_cases
attribute which is used by extinct_prob() and detect_extinct(),
therefore if you modify the output of scenario_sim() before passing
to extinct_prob() be careful not to drop the attribute (e.g.
from subsetting the data.table).
Value
extinct_prob(): a single numeric with the probability of extinction
detect_extinct(): a data.table, with two columns sim and extinct, for a binary
classification of whether the outbreak went extinct in each simulation
replicate. 1 is an outbreak that went extinct, 0 if not.
Examples
res <- scenario_sim(
n = 10,
initial_cases = 1,
offspring = offspring_opts(
community = \(n) rnbinom(n = n, mu = 2.5, size = 0.16),
isolated = \(n) rnbinom(n = n, mu = 0.5, size = 1)
),
delays = delay_opts(
incubation_period = \(n) rweibull(n = n, shape = 2.32, scale = 6.49),
onset_to_isolation = \(n) rweibull(n = n, shape = 1.65, scale = 4.28)
),
event_probs = event_prob_opts(
asymptomatic = 0,
presymptomatic_transmission = 0.5,
symptomatic_traced = 0.2
),
interventions = intervention_opts(quarantine = FALSE),
sim = sim_opts(cap_max_days = 350, cap_cases = 4500)
)
# calculate probability of extinction
extinct_prob(res)
# determine if each outbreak simulation replicate has gone extinct
detect_extinct(res)
# calculate extinction in the last 2 weeks of the simulated outbreak
# (i.e. the penultimate and last week of the outbreak)
extinct_prob(res, extinction_week = max(res$week) - 1)
# calculate extinction as no new cases between weeks 12 and 16 of the outbreak
extinct_prob(res, extinction_week = 12:16)
Convert symptom onset times to generation times
Description
Samples generation times from a skew-normal distribution based on relative
symptom onset times (symptom_onset_time - exposure_time), ensuring all
generation times are at least latent_period. The location parameter of the
skew-normal distribution is set to the relative symptom onset times.
Usage
incubation_to_generation_time(
symptom_onset_time,
exposure_time = rep(0, length(symptom_onset_time)),
alpha,
latent_period = 0
)
Arguments
symptom_onset_time |
a positive |
exposure_time |
a non-negative |
alpha |
a |
latent_period |
a non-negative If |
Value
a numeric vector of generation times of equal length to the vector
input to symptom_onset_time: the i-th element of the vector contains a
sample from the generation time distribution of an individual with
incubation period given by the i-th element of the symptom_onset_time
vector. The lower bound of the output generation time vector is set by the
latent_period, to prevent transmission before becoming infectious.
Examples
incubation_to_generation_time(
symptom_onset_time = c(1, 2, 3, 4, 1),
alpha = 2
)
Create a list of intervention settings to run the ringbp model
Description
Create a list of intervention settings to run the ringbp model
Usage
intervention_opts(quarantine = FALSE, test_sensitivity = 1)
Arguments
quarantine |
a |
test_sensitivity |
a A scalar is treated as a constant test sensitivity over the whole
simulation. A Only symptomatic individuals that do not self-isolate are tested; a
false-negative result means the case is not isolated via the testing
pathway (see |
Value
A list with class <ringbp_intervention_opts>.
Examples
# quarantine is not active (default)
intervention_opts(quarantine = FALSE)
# quarantine is active
intervention_opts(quarantine = TRUE)
# 20% of tests return a false-negative
intervention_opts(test_sensitivity = 0.8)
# time-varying test sensitivity, in the first 30 days of the outbreak
# sensitivity is 0.5, then after 30 days, sensitivity improves to 0.8
intervention_opts(
test_sensitivity = \(t) ifelse(t > 30, yes = 0.8, no = 0.5)
)
Create a list of offspring distributions to run the ringbp model
Description
Create a list of offspring distributions to run the ringbp model
Usage
offspring_opts(community, isolated, asymptomatic = community)
Arguments
community |
a |
isolated |
a |
asymptomatic |
a |
Details
If asymptomatic is not provided it will be specified as the same as
community meaning transmission of subclinical cases to be equal to
clinical cases unless specified otherwise.
Value
A list with class <ringbp_offspring_opts>.
Examples
# Negative binomial offspring distributions with:
# Community R0 of 2.5 and dispersion of 0.16
# Isolated R0 of 0.5 and dispersion of 1
# Asymptomatic R0 of 2.5 and dispersion of 0.16
offspring_opts(
community = \(n) rnbinom(n = n, mu = 2.5, size = 0.16),
isolated = \(n) rnbinom(n = n, mu = 0.5, size = 1),
asymptomatic = \(n) rnbinom(n = n, mu = 2.5, size = 0.16)
)
Control whether outbreak simulation continues stepping
Description
Used in a while loop to determine whether the outbreak_model()
continues to call outbreak_step(), or to end the simulation.
Usage
outbreak_continue(case_data, sim)
Arguments
case_data |
a |
sim |
a |
Value
a logical scalar: whether the outbreak is still active and should
continue (TRUE) or if the outbreak is extinct or has reached a stopping
criterion (FALSE).
Run a single instance of the branching process model
Description
Run a single instance of the branching process model
Usage
outbreak_model(
initial_cases,
offspring,
delays,
event_probs,
interventions,
sim
)
Arguments
initial_cases |
a non-negative |
offspring |
a |
delays |
a |
event_probs |
a |
interventions |
a |
sim |
a |
Value
data.table of cases by week, cumulative cases, and the effective
reproduction number of the outbreak. data.table columns are:
-
$week:numeric -
$weekly_cases:numeric -
$cumulative:numeric -
$effective_r0:numeric -
$cases_per_gen:list
Examples
set.seed(1)
offspring <- offspring_opts(
community = \(n) rnbinom(n = n, mu = 2.5, size = 0.16),
isolated = \(n) rnbinom(n = n, mu = 0.5, size = 1),
asymptomatic = \(n) rnbinom(n = n, mu = 2.5, size = 0.16)
)
delays <- delay_opts(
incubation_period = \(n) rweibull(n = n, shape = 2.32, scale = 6.49),
onset_to_isolation = \(n) rweibull(n = n, shape = 1.65, scale = 4.28)
)
event_probs <- event_prob_opts(
asymptomatic = 0,
presymptomatic_transmission = 0.5,
symptomatic_traced = 0.2
)
interventions <- intervention_opts(quarantine = FALSE)
out <- outbreak_model(
initial_cases = 1,
offspring = offspring,
delays = delays,
event_probs = event_probs,
interventions = interventions,
sim = sim_opts()
)
out
Set up initial cases for branching process
Description
Set up initial cases for branching process
Usage
outbreak_setup(initial_cases, delays, event_probs, interventions)
Arguments
initial_cases |
a non-negative |
delays |
a |
event_probs |
a |
interventions |
a |
Value
data.table of cases in outbreak so far. data.table columns are:
-
$exposure:numeric -
$asymptomatic:logical -
$caseid:integer -
$infector:numeric -
$traced:logical -
$onset:numeric -
$new_cases:integer -
$self_isolate:logical -
$isolated_time:numeric -
$sampled:logical
Examples
delays <- delay_opts(
incubation_period = \(n) rweibull(n = n, shape = 2.32, scale = 6.49),
onset_to_isolation = \(n) rweibull(n = n, shape = 1.65, scale = 4.28)
)
event_probs <- event_prob_opts(
asymptomatic = 0,
presymptomatic_transmission = 0.15,
symptomatic_traced = 0
)
interventions <- intervention_opts()
# generate initial cases
case_data <- outbreak_setup(
initial_cases = 5,
delays = delays,
event_probs = event_probs,
interventions = interventions
)
case_data
Move forward one generation in the branching process
Description
Move forward one generation in the branching process
Usage
outbreak_step(case_data, offspring, delays, event_probs, interventions)
Arguments
case_data |
a |
offspring |
a |
delays |
a |
event_probs |
a |
interventions |
a |
Details
Each new case is assigned an isolation time (isolated_time) as the
earliest of up to three pathways; a case to which no pathway applies is
never isolated (isolated_time is Inf):
-
Self-isolation: a symptomatic case self-isolates with probability
symptomatic_self_isolate(fromevent_prob_opts()), entering isolation anonset_to_self_isolationdelay (fromdelay_opts()) after symptom onset. Self-isolating cases are not tested. -
Testing: a symptomatic case that does not self-isolate is tested and returns a positive result with probability
test_sensitivity(fromintervention_opts()), entering isolation anonset_to_isolationdelay after symptom onset. A false-negative result does not isolate the case via this pathway. -
Tracing: a case whose infector is symptomatic is traced with probability
symptomatic_traced(fromevent_prob_opts()). Whenquarantineis active (fromintervention_opts()) tracing is exposure-based: a traced case is isolated when its infector is isolated, regardless of its own symptom status. Withoutquarantine, only a traced symptomatic case is isolated, and no earlier than its own symptom onset.
Self-isolation and testing are symptom-based, so asymptomatic cases are
isolated only via the tracing pathway, and only when quarantine is active.
Value
A list with three elements:
-
$cases: adata.tablewith case data -
$effective_r0: anumericwith the effective reproduction number -
$cases_in_gen: anumericwith the number of new cases in that generation
Examples
offspring <- offspring_opts(
community = \(n) rnbinom(n = n, mu = 2.5, size = 0.16),
isolated = \(n) rnbinom(n = n, mu = 0, size = 1),
asymptomatic = \(n) rnbinom(n = n, mu = 1.25, size = 0.16)
)
delays <- delay_opts(
incubation_period = \(n) rweibull(n = n, shape = 2.32, scale = 6.49),
onset_to_isolation = \(n) rweibull(n = n, shape = 1.65, scale = 4.28)
)
event_probs <- event_prob_opts(
asymptomatic = 0,
presymptomatic_transmission = 0.15,
symptomatic_traced = 0
)
interventions <- intervention_opts(quarantine = FALSE)
# generate initial cases
case_data <- outbreak_setup(
initial_cases = 5,
delays = delays,
event_probs = event_probs,
interventions = interventions
)
case_data
# generate next generation of cases
out <- outbreak_step(
case_data = case_data,
offspring = offspring,
delays = delays,
event_probs = event_probs,
interventions = interventions
)
case_data <- out[[1]]
case_data
Estimate skew normal alpha parameter from proportion of presymptomatic transmission
Description
Estimate skew normal alpha parameter from proportion of presymptomatic transmission
Usage
presymptomatic_transmission_to_alpha(presymptomatic_transmission)
Arguments
presymptomatic_transmission |
a |
Details
Since there isn't any analytical expression for linking the two, the value of alpha that corresponds to the given proportion presymptomatic is obtained via numeric optimisation.
Value
A numeric scalar: The $minimum output from optimise() to find
the best alpha parameter to get the desired proportion of presymptomatic
transmission.
Sample the offspring distributions for cases that can be in either the community, isolated or asymptomatic states and transition between states
Description
Samples from the offspring distributions (see offspring_opts()) and adds
the next generation of transmission events by reference to case_data.
The generation times for each infector-infectee pair is also sampled and
is returned from the function.
Usage
sample_offspring(case_data, offspring, alpha, latent_period)
Arguments
case_data |
a |
offspring |
a |
alpha |
a |
latent_period |
a non-negative If |
Details
A case's offspring cannot simply be sampled from a single
offspring distribution, as the case might become isolated before
infecting some or all of those cases. To account for cases that
transition between states (community -> isolated for symptomatic
cases, asymptomatic -> isolated for asymptomatic cases) we sample
offspring from both the pre-isolation and the post-isolation (isolated)
distributions, assign all new cases a generation time, and then discard
pre-isolation offspring with a generation time after the isolation time
and post-isolation offspring with a generation time before it.
Value
A numeric vector with the generation times for the new cases
exposure/infection times.
Note The case_data supplied to the function is modified by
references, see data.table::set() for more information.
Run a specified number of simulations with identical parameters
Description
Run a specified number of simulations with identical parameters
Usage
scenario_sim(
n,
initial_cases,
offspring,
delays,
event_probs,
interventions,
sim
)
Arguments
n |
a positive |
initial_cases |
a non-negative |
offspring |
a |
delays |
a |
event_probs |
a |
interventions |
a |
sim |
a |
Value
A data.table object returning the results for multiple simulations
using the same set of parameters. The table has columns
week: The week in the simulation.
weekly_cases: The number of new cases that week.
cumulative: The cumulative cases.
effective_r0: The effective reproduction rate for the whole simulation
cases_per_gen: A list column with the cases per generation. This is repeated each row.
sim: Index column for which simulation.
Examples
offspring <- offspring_opts(
community = \(n) rnbinom(n = n, mu = 2.5, size = 0.16),
isolated = \(n) rnbinom(n = n, mu = 0, size = 1),
asymptomatic = \(n) rnbinom(n = n, mu = 2.5, size = 0.16)
)
delays <- delay_opts(
incubation_period = \(n) rweibull(n = n, shape = 2.32, scale = 6.49),
onset_to_isolation = \(n) rweibull(n = n, shape = 2.5, scale = 5)
)
event_probs <- event_prob_opts(
asymptomatic = 0,
presymptomatic_transmission = 0.3,
symptomatic_traced = 0
)
interventions <- intervention_opts(quarantine = TRUE)
sim <- sim_opts(
cap_max_days = 365,
cap_cases = 2000
)
res <- scenario_sim(
n = 5,
initial_cases = 5,
offspring = offspring,
delays = delays,
event_probs = event_probs,
interventions = interventions,
sim = sim
)
res
Create a list of simulation control options for the ringbp model
Description
Create a list of simulation control options for the ringbp model
Usage
sim_opts(cap_max_days = 350, cap_cases = 5000)
Arguments
cap_max_days |
a positive |
cap_cases |
a positive |
Value
A list with class <ringbp_sim_opts>.
Examples
# default simulation control options
sim_opts()
# specifying custom simulation control options
sim_opts(
cap_max_days = 140,
cap_cases = 1000
)