| Title: | Bayesian Compartmental Infection Models from Individual Outcomes |
| Version: | 0.1.0 |
| Description: | Fit Bayesian compartmental infection models (such as susceptible-infected-recovered and multi-compartment hidden Markov variants) from individual-level outcome data. Models are composed from infection-process and observation-process components and fit using Stan via 'rstan'. |
| License: | MIT + file LICENSE |
| Encoding: | UTF-8 |
| Language: | en-US |
| Biarch: | true |
| Depends: | R (≥ 4.1.0) |
| Imports: | checkmate, dplyr, flexstanr (≥ 0.2.0), methods, posterior, Rcpp (≥ 0.12.0), RcppParallel (≥ 5.0.1), rstan (≥ 2.18.1), rstantools (≥ 2.5.0), stats, tidyr |
| LinkingTo: | BH (≥ 1.66.0), Rcpp (≥ 0.12.0), RcppEigen (≥ 0.3.3.3.0), RcppParallel (≥ 5.0.1), rstan (≥ 2.18.1), StanHeaders (≥ 2.18.0) |
| SystemRequirements: | GNU make |
| Suggests: | bayesplot, ggplot2, knitr, lintr, patchwork, pkgload, rmarkdown, roxygen2, roxyglobals, spelling, testthat (≥ 3.0.0), withr |
| VignetteBuilder: | knitr |
| Config/testthat/edition: | 3 |
| URL: | https://accidda.github.io/hestia/, https://github.com/ACCIDDA/hestia |
| BugReports: | https://github.com/ACCIDDA/hestia/issues |
| LazyData: | true |
| LazyDataCompression: | xz |
| Config/roxyglobals/filename: | globals.R |
| Config/roxyglobals/unique: | FALSE |
| Config/roxygen2/version: | 8.1.0 |
| NeedsCompilation: | yes |
| Packaged: | 2026-10-08 15:02:04 UTC; runner |
| Author: | Claire Perrin Smith
|
| Maintainer: | Claire Perrin Smith <clairesmith6995@gmail.com> |
| Repository: | CRAN |
| Date/Publication: | 2026-10-20 15:00:02 UTC |
The 'hestia' package.
Description
A DESCRIPTION OF THE PACKAGE
Author(s)
Maintainer: Claire Perrin Smith clairesmith6995@gmail.com (ORCID)
Authors:
Claire Perrin Smith clairesmith6995@gmail.com (ORCID)
Jack Goodall jackwgoodall@hotmail.com
References
Stan Development Team (NA). RStan: the R interface to Stan. R package version 2.32.7. https://mc-stan.org
See Also
Useful links:
Report bugs at https://github.com/ACCIDDA/hestia/issues
Validate the init_probs argument passed to run_model()
Description
Initial state probabilities must be a finite non-negative numeric vector that sums to roughly one.
Usage
check_init_probs(init_probs)
Arguments
init_probs |
the vector of initial state probabilities. |
Validate the assembled model lists passed to run_model()
Description
Validate the assembled model lists passed to run_model()
Usage
check_models(inf_model, obs_model)
Arguments
inf_model |
output of |
obs_model |
output of |
Validate a single observation-process specification
Description
Each observation is a named numeric vector of detection probabilities, one
entry per compartment, with values in [0, 1].
Usage
check_observation(obs, nm = "observation")
Arguments
obs |
a single observation specification. |
nm |
its name, used in error messages. |
Validate the gamma-style transition-rate values passed to progress()
Description
Each rate value must be either NA (fit the parameter) or a positive
numeric (use the supplied value).
Usage
check_rate_dots(dots)
Arguments
dots |
the unlisted |
Validate the observation data frame passed to run_model()
Description
Validate the observation data frame passed to run_model()
Usage
check_run_data(data, obs_model)
Arguments
data |
the participant-level data frame. |
obs_model |
output of |
Validate the split argument shared by transmit() and progress()
Description
split may be left as a single NA (no split), a character vector of
parameter names, or a numeric vector of proportions. This only checks the
broad type and finiteness; the detailed length/sum rules stay in
split_check().
Usage
check_split(split)
Arguments
split |
the split specification to validate. |
Validate the from/to arguments shared by transmit() and progress()
Description
Validate the from/to arguments shared by transmit() and progress()
Usage
check_to_from(from, to)
Arguments
from |
origin compartment, expected to be a single non-empty string. |
to |
destination compartment(s), expected to be a non-empty character vector. |
Create Transmission Probability Matrix
Description
Create Transmission Probability Matrix
Usage
get_transmission_details(inf_model)
Arguments
inf_model |
infection process model object yielded by make_infection_model() |
Value
A list with the following entries:
"states", a character vector of state names
"trans_matrix", a matrix with transition rate values between origin (column) and destination (row) compartments where given. Where no values are provided for transition rates the entry is equal to 1e-10.
"mult_matrix", a matrix with split values for the transition between origin (column) and destination (row) compartments where given. Where no split values are provided for transition rates the entry is equal to 1.
"trans_to_fit", a data frame with information on all transitions within the model, with parameter indexing details if the transition rate is being fit
"mult_to_fit", a data frame with information on all splits specified in the model, with parameter indexing details if the split is being fit
"inf_states", numeric values corresponding to the indices in "states" which are the infectious states
"mult_ih_inf_probs", indicator for whether infectious states have shared or separate inta-household infection probabilities. If FALSE then all infection probabilities are shared across infectious compartments.
Examples
# Split the infectious compartment into symptomatic (I_s) and asymptomatic
# (I_a) infections, with separate intra-household infection probabilities.
inf_model <- make_infection_model(
transmit(from = "S",
to = c("I_s", "I_a"),
source = c("I_s", "I_a"),
split = "phi"),
progress(from = "I_s", to = "R", gamma_s = NA),
progress(from = "I_a", to = "R", gamma_a = NA),
mult_ih_inf_probs = TRUE)
get_transmission_details(inf_model)
Check whether an undirected adjacency matrix is fully connected
Description
Breadth-first reachability from the first node. Replaces a single-use dependency on Claddis::is_graph_connected (the only reason hestia imported Claddis, whose heavy dependency tree failed to build on R-devel macOS).
Usage
graph_connected(graph)
Arguments
graph |
square symmetric 0/1 adjacency matrix. |
Value
TRUE if every node is reachable from the first, else FALSE.
Inverse Logit Transformation
Description
Inverse Logit Transformation
Usage
inv_logit(x)
Arguments
x |
Numeric value |
Value
A numeric value between 0 and 1.
Logit Transformation
Description
Logit Transformation
Usage
logit(x)
Arguments
x |
Numeric value between 0 and 1 |
Value
A numeric value.
Build Infection Process Model
Description
Build Infection Process Model
Usage
make_infection_model(..., mult_ih_inf_probs = FALSE, mult_eh_inf_probs = FALSE)
Arguments
... |
|
mult_ih_inf_probs |
If FALSE then all intra-household infection probabilities are shared across infectious compartments. If TRUE, each infection compartment has a distinct probability. |
mult_eh_inf_probs |
If FALSE then all extra-household infection probabilities are shared across infectious compartments. If TRUE, each infection compartment has a distinct probability. |
Value
A data frame with a row for each unique transition in the infection process model and the following columns:
"from", the name of the origin compartment
"to", the name of the destination compartment
"source", NA (so output columns match with
transmit)"rate_name", name of transition rate parameter if fitting
"rate_value", numeric value of transition rate if not fitting
"split_name", name of split parameter if fitting
"split_value", numeric value of split if not fitting
"source", names of compartment(s) that are the source of new infections
"mult_ih_inf_probs", a logical indicator for whether infectious compartments have separate (
TRUE) or shared (FALSE) intra-household infection probabilities
Examples
# Basic SIR model with recovery rate gamma to be fit
make_infection_model(transmit(from = "S", to = "I"),
progress(from = "I", to = "R", gamma = NA))
# Split the infectious compartment into symptomatic (I_s) and asymptomatic
# (I_a) infections, with separate intra-household infection probabilities.
make_infection_model(
transmit(from = "S",
to = c("I_s", "I_a"),
source = c("I_s", "I_a"),
split = "phi"),
progress(from = "I_s", to = "R", gamma_s = NA),
progress(from = "I_a", to = "R", gamma_a = NA),
mult_ih_inf_probs = TRUE)
Make Observation Process Model
Description
Make Observation Process Model
Usage
make_observation_model(...)
Arguments
... |
A series of named vectors. Each vector corresponds to an observation type. Each entry in the vector is named for the corresponding compartment in the infection process model. The value is the probability of observing a positive observation given the individual is in the compartment. |
Value
A list with one entry for each observation type.
Examples
# Observation process for an SIR model with two observations, PCR test
# results and presence of IgG antibodies.
make_observation_model(
pcr = c("S" = 0.05, "I" = 0.95, "R" = 0.05),
igg = c("S" = 0.01, "I" = 0.01, "R" = 0.8)
)
Create Data for Stan Model
Description
Create Data for Stan Model
Usage
make_stan_data(
inf_model,
obs_model,
data,
init_probs,
t_start = 1,
epsilon = 1e-10,
ih_cov = NULL,
eh_cov = NULL
)
Arguments
inf_model |
Infection process model object generated by make_infection_model |
obs_model |
Observation process model object generated by make_observation_model |
data |
data frame with columns the following columns:
|
init_probs |
vector of initial probabilities for each infection process model state |
t_start |
integer value corresponding to the start of model time |
epsilon |
very small number to use for zero probability transitions |
ih_cov |
NULL for run without covariates, otherwise data frame with intra-household covariates for each participant |
eh_cov |
NULL for run without covariates, otherwise data frame with extra-household covariates for each participant |
Value
A list with data elements for input to stan model.
Define a non-infection transition
Description
Defines a state transition in the infection process model which does not represent an transmission (infection) event
Usage
progress(from, to, split = NA, ...)
Arguments
from |
string giving name of origin compartment |
to |
string or vector of strings giving the name of the destination compartment |
split |
an optional character or numeric vector indicating what
proportion of individuals transition into each of the |
... |
Argument specifying the name and optionally the value of the
transition rate parameter. For example if the parameter name is "gamma" and
it is being fit this argument should be |
Value
Data frame with a row for each unique transition and the following columns:
"from", the name of the origin compartment
"to", the name of the destination compartment
"source", NA (so output columns match with
transmit)"rate_name", name of transition rate parameter if fitting
"rate_value", numeric value of transition rate if not fitting
"split_name", name of split parameter if fitting
"split_value", numeric value of split if not fitting
Examples
# Transition from compartment A to B which occurs at rate gamma where
# gamma is a user-specified value of 0.2
progress(from = "A", to = "B", gamma = 0.2)
# Transition from compartment A to B which occurs at rate gamma where
# gamma is fit
progress(from = "A", to = "B", gamma = NA)
# Transition from compartment A split into two destination compartments, B1
# and B2, were individuals leave A at rate delta (fit) and phi (fit) is the
# proportion of those who leave A who go into B1 (i.e. 1-phi go into B2).
# gamma is fit
progress(from = "A", to = c("B1", "B2"), split = "phi", delta = NA)
Objects exported from other packages
Description
These objects are imported from other packages. Follow the links below to see their documentation.
- flexstanr
Extract chains and renames with user-provided parameter names
Description
Extract chains and renames with user-provided parameter names
Usage
rename_chains(inf_model, model_output, save_llik, save_states)
Arguments
inf_model |
Infection process model object generated by make_infection_model |
model_output |
A list generated within run_model which contains the stanfit, the stan input data, and covariate names |
save_llik |
whether to write the per-household log-likelihood
( |
save_states |
whether to write the per-participant log forward
probabilities ( |
Value
A draws_array object with chains for each model parameter
Run Household Transmission Model
Description
Run Household Transmission Model
Usage
run_model(
inf_model,
obs_model,
data,
init_probs,
t_start = 1,
epsilon = 1e-10,
ih_cov = NULL,
eh_cov = NULL,
init = NULL,
save_llik = FALSE,
save_states = FALSE,
stan_opts = stan_options()
)
Arguments
inf_model |
Infection process model object generated by make_infection_model |
obs_model |
Observation process model object generated by make_observation_model |
data |
data frame with columns the following columns:
|
init_probs |
vector of initial probabilities for each infection process model state |
t_start |
integer value corresponding to the start of model time |
epsilon |
very small number to use for zero probability transitions |
ih_cov |
NULL for run without covariates, otherwise data frame with intra-household covariates for each participant |
eh_cov |
NULL for run without covariates, otherwise data frame with extra-household covariates for each participant |
init |
initial conditions for MCMC chains |
save_llik |
whether to write the per-household log-likelihood
( |
save_states |
whether to write the per-participant log forward
probabilities ( |
stan_opts |
a named list of Stan sampler options, as produced by
|
Value
draws_array object with chains for each model parameter
Examples
# Subset sir package data to 10 households (for speedy example)
sir_sub <- sir[sir$hh_id <= 10, ]
# Make infetion process model for SIR model
inf_mod <- make_infection_model(
transmit(from = "S", to = "I"),
progress(from = "I", to = "R", gamma = NA))
# Make observation process model
obs_mod <- make_observation_model(
pcr = c("S" = 0.05, "I" = 0.95, "R" = 0.05),
igg = c("S" = 0.01, "I" = 0.01, "R" = 0.8))
# Fitting the Stan model is slow, so it is not run on CRAN.
run_model(inf_model = inf_mod,
obs_model = obs_mod,
data = sir_sub,
init_probs = c(1 - 2 * 1e-10, 1e-10, 1e-10))
Simulated SIIR household data
Description
Individual-level outcomes simulated from an SIIR model for 500 households, in
which infection splits into symptomatic (Is) and asymptomatic (Ia)
compartments. The two infectious compartments have separate intra-household
infection probabilities. Each individual has three binary observations: one
informative about active infection (e.g. a PCR test), one informative about
recovery (e.g. an IgG antibody test), and one indicating symptoms.
Usage
siir
Format
A data frame with one row per individual per day and the following columns:
- t
Day of observation.
- part_id
Participant identifier within the household.
- enroll
Enrollment indicator (1 = enrolled, 0 = not enrolled).
- state
True latent compartment (1 = S, 2 = Is, 3 = Ia, 4 = R).
- hh_size
Household size.
- hh_id
Household identifier.
- pcr
Binary outcome informative about active infection.
- igg
Binary outcome informative about recovery.
- symp
Binary outcome indicating symptoms.
Source
Generated by data-raw/siir_data.R.
Fitted draws for the SIIR model
Description
Posterior draws from run_model() fit to the siir data using an infection
process with separate symptomatic and asymptomatic compartments. Bundling the
result lets the vignette display model output without re-running the Stan
model. Parameters are on the natural (model) scale: probabilities, rates, and
the symptomatic split are returned in their original units rather than on the
logit fitting scale.
Usage
siir_res
Format
A posterior draws_array with parameters eh_prob, ih_prob_Is,
ih_prob_Ia, gamma_s, gamma_a, and phi.
Source
Generated by data-raw/siir_res.R.
Simulated SIR household data
Description
Individual-level outcomes simulated from a basic susceptible-infected-recovered (SIR) model for 500 households. Everyone starts susceptible, the daily extra-household infection probability is 1%, and the daily intra-household infection probability is 5%. Each individual has two binary observations: one informative about active infection (e.g. a PCR test) and one informative about recovery (e.g. an IgG antibody test).
Usage
sir
Format
A data frame with one row per individual per day and the following columns:
- t
Day of observation.
- part_id
Participant identifier within the household.
- enroll
Enrollment indicator (1 = enrolled, 0 = not enrolled).
- state
True latent compartment (1 = S, 2 = I, 3 = R).
- hh_size
Household size.
- hh_id
Household identifier.
- pcr
Binary outcome informative about active infection.
- igg
Binary outcome informative about recovery.
Source
Generated by data-raw/sir_data.R.
Simulated SIR household data with covariates
Description
Individual-level outcomes simulated from a basic SIR model for 500 households, together with two binary individual-level covariates that affect the intra- and extra-household infection probabilities. Used to demonstrate fitting covariate effects.
Usage
sir_cov
Format
A list with two elements:
- observations
A data frame of outcomes with the same columns as sir.
- covariates
A data frame with one row per individual and two binary covariate columns,
x1andx2.
Source
Generated by data-raw/sir_cov_data.R.
Fitted draws for the SIR model with covariates
Description
Posterior draws from run_model() fit to sir_cov with both intra- and
extra-household covariates. Bundling the result lets the vignette display
model output without re-running the Stan model. Parameters are on the natural
(model) scale: infection probabilities and rates in their original units and
covariate coefficients exponentiated, rather than on the logit and log
fitting scales.
Usage
sir_cov_res
Format
A posterior draws_array with parameters eh_prob, ih_prob,
gamma, x1_eh, x2_eh, x1_ih, and x2_ih.
Source
Generated by data-raw/sir_cov_res.R.
Fitted draws for the basic SIR model
Description
Posterior draws from run_model() fit to the sir data using a basic SIR
infection process (fitting the recovery rate) and a two-test observation
process. Bundling the result lets the vignette display model output without
re-running the Stan model. Parameters are on the natural (model) scale:
probabilities and rates are returned in their original units rather than on
the logit fitting scale.
Usage
sir_res
Format
A posterior draws_array with parameters eh_prob, ih_prob,
and gamma.
Source
Generated by data-raw/sir_res.R.
Checking split parameter specification
Description
Utility function for checking whether split parameter is properly defined
Usage
split_check(to, split)
Arguments
to |
Character vector giving the name(s) of the destination compartment |
split |
Numeric or character vector indicating how people moving out of the starting compartment are split between the destination compartments |
Checking to and from parameter specification
Description
Utility function for checking whether to and from parameters are properly defined
Usage
to_from_check(to, from)
Arguments
to |
Character vector giving the name(s) of the destination compartment |
from |
string giving name of origin compartment |
Define a infection transition
Description
Defines a state transition in the infection process model which is the result of a transmission (infection) event
Usage
transmit(from, to, source = NA, split = NA)
Arguments
from |
string giving name of origin compartment |
to |
string giving the name of the destination compartment |
source |
string (or vector of strings) designating which compartments are infectious. If NA, the destination compartment is presumed to be the infectious compartment. |
split |
an optional character or numeric vector indicating what
proportion of individuals transition into each of the |
Value
Data frame with a row for each unique transition and the following columns:
"from", the name of the origin compartment
"to", the name of the destination compartment
"split_name", name of split parameter if fitting
"split_value", numeric value of split if not fitting
"source", names of compartment(s) that are the source of new infections i.e. the infectious compartments
Examples
# Specify S > E transition in an SEIR model
transmit(from = "S", to = "E", source = "I")
# Upon infection, individuals either enter Is (symptomatic infections) or
# Ia (asymptomatic infection) where 30% of infections are symptomatic.
transmit(from = "S", to = c("Is", "Ia"), split = 0.3)