Skip to contents

Fit age-stratified seroprevalence to parametric hierarchical Bayesian models. Supported models including Farrington model (2 and 3 parameters variants) and Log Logistic model

Usage

hierarchical_bayesian_model(
  data,
  age_col = "age",
  pos_col = "pos",
  tot_col = "tot",
  status_col = "status",
  type = "far3",
  chains = 1,
  warmup = 1500,
  iter = 5000
)

Arguments

data

the input data frame, must either have columns for `age`, `pos`, `tot` (for aggregated data) OR `age`, `status` (for linelisting data)

age_col

name of the `age` column (default age_col="age").

pos_col

name of the `pos` column (default pos_col="pos").

tot_col

name of the `tot` column (default tot_col="tot").

status_col

name of the `status` column (default status_col="status").

type

type of model ("far2", "far3" or "log_logistic")

chains

number of Markov chains

warmup

number of warmup runs

iter

number of iterations

Value

a list of class hierarchical_bayesian_model with the following items

datatype

type of datatype used for model fitting (aggregated or linelisting)

df

the dataframe used for fitting the model

type

type of bayesian model "far2", "far3" or "log_logistic"

info

a stanfit object for the fitted result

sp

seroprevalence

foi

force of infection

sp_func

function to compute seroprevalence given age and model parameters

foi_func

function to compute force of infection given age and model parameters

Details

Consider a model for prevalence that has a parametric form \(\pi(a_i, \alpha)\) where \(\alpha\) is a parameter vector

Under a Bayesian framework, we can constraint the parameter space of the prior distribution \(P(\alpha)\) to achieve monotonicity of the posterior distribution \(P(\pi_1, \pi_2, ..., \pi_m|y,n)\)

Where:

- \(n = (n_1, n_2, ..., n_m)\) and \(n_i\) is the sample size at age \(a_i\)

- \(y = (y_1, y_2, ..., y_m)\) and \(y_i\) is the number of infected individual from the \(n_i\) sampled subjects

For Farrington model with 3 parameters, prevalence is formulated as follow

$$ \pi (a) = 1 - exp\{ \frac{\alpha_1}{\alpha_2}ae^{-\alpha_2 a} + \frac{1}{\alpha_2}(\frac{\alpha_1}{\alpha_2} - \alpha_3)(e^{-\alpha_2 a} - 1) -\alpha_3 a \} $$

The likelihood model is defined as \(y_i \sim Bin(n_i, \pi_i), \text{ for } i = 1,2,3,...m\)

The constraint on the parameter space can be incorporated by assuming truncated normal distribution for the components of \(\alpha\), \(\alpha = (\alpha_1, \alpha_2, \alpha_3)\) in \(\pi_i = \pi(a_i,\alpha)\)

The flat hyperpriors are defined as \(\mu_j \sim \mathcal{N}(0, 10000)\) and \(\tau^{-2}_j \sim \Gamma(100,100)\)

For Farrington model with 2 parameters, it is equivalent to the previous model with \(\alpha_3 = 0\)

For Log logistic model, seroprevalence is instead defined as

$$\pi(a) = \frac{\beta a^\alpha}{1 + \beta a^\alpha}, \text{ } \alpha, \beta > 0$$

The likelihood is similarly defined as \(y_i \sim Bin(n_i, \pi_i))\)

The prior model of \(\alpha_1\) is specified as \(\alpha_1 \sim \text{truncated } \mathcal{N}(\mu_1, \tau_1)\) with flat hyperpriors as in Farrington model

\(\beta\) is constrained to be positive by specifying \(\alpha_2 \sim \mathcal{N}(\mu_2, \tau_2)\)

Refer to section Chapter 10.3 of the the book by Hens et al. (2012) for further details.

References

Hens, Niel, Ziv Shkedy, Marc Aerts, Christel Faes, Pierre Van Damme, and Philippe Beutels. 2012. Modeling Infectious Disease Parameters Based on Serological and Social Contact Data: A Modern Statistical Perspective. tatistics for Biology and Health. Springer New York. doi:10.1007/978-1-4614-4072-7 .

Examples

# \donttest{
df <- mumps_uk_1986_1987
model <- hierarchical_bayesian_model(df, type="far3")
#> 
#> SAMPLING FOR MODEL 'fra_3' NOW (CHAIN 1).
#> Chain 1: Rejecting initial value:
#> Chain 1:   Log probability evaluates to log(0), i.e. negative infinity.
#> Chain 1:   Stan can't start sampling from this initial value.
#> Chain 1: Rejecting initial value:
#> Chain 1:   Log probability evaluates to log(0), i.e. negative infinity.
#> Chain 1:   Stan can't start sampling from this initial value.
#> Chain 1: 
#> Chain 1: Gradient evaluation took 0.000111 seconds
#> Chain 1: 1000 transitions using 10 leapfrog steps per transition would take 1.11 seconds.
#> Chain 1: Adjust your expectations accordingly!
#> Chain 1: 
#> Chain 1: 
#> Chain 1: Iteration:    1 / 5000 [  0%]  (Warmup)
#> Chain 1: Iteration:  500 / 5000 [ 10%]  (Warmup)
#> Chain 1: Iteration: 1000 / 5000 [ 20%]  (Warmup)
#> Chain 1: Iteration: 1500 / 5000 [ 30%]  (Warmup)
#> Chain 1: Iteration: 1501 / 5000 [ 30%]  (Sampling)
#> Chain 1: Iteration: 2000 / 5000 [ 40%]  (Sampling)
#> Chain 1: Iteration: 2500 / 5000 [ 50%]  (Sampling)
#> Chain 1: Iteration: 3000 / 5000 [ 60%]  (Sampling)
#> Chain 1: Iteration: 3500 / 5000 [ 70%]  (Sampling)
#> Chain 1: Iteration: 4000 / 5000 [ 80%]  (Sampling)
#> Chain 1: Iteration: 4500 / 5000 [ 90%]  (Sampling)
#> Chain 1: Iteration: 5000 / 5000 [100%]  (Sampling)
#> Chain 1: 
#> Chain 1:  Elapsed Time: 17.621 seconds (Warm-up)
#> Chain 1:                10.803 seconds (Sampling)
#> Chain 1:                28.424 seconds (Total)
#> Chain 1: 
#> Warning: There were 790 divergent transitions after warmup. See
#> https://mc-stan.org/misc/warnings.html#divergent-transitions-after-warmup
#> to find out why this is a problem and how to eliminate them.
#> Warning: Examine the pairs() plot to diagnose sampling problems
#> Warning: Bulk Effective Samples Size (ESS) is too low, indicating posterior means and medians may be unreliable.
#> Running the chains for more iterations may help. See
#> https://mc-stan.org/misc/warnings.html#bulk-ess
#> Warning: Tail Effective Samples Size (ESS) is too low, indicating posterior variances and tail quantiles may be unreliable.
#> Running the chains for more iterations may help. See
#> https://mc-stan.org/misc/warnings.html#tail-ess
model$info
#> Inference for Stan model: fra_3.
#> 1 chains, each with iter=5000; warmup=1500; thin=1; 
#> post-warmup draws per chain=3500, total post-warmup draws=3500.
#> 
#>                  mean se_mean      sd     2.5%      25%      50%      75%
#> alpha1           0.14    0.00    0.01     0.13     0.13     0.14     0.14
#> alpha2           0.20    0.00    0.01     0.18     0.19     0.20     0.20
#> alpha3           0.01    0.00    0.01     0.00     0.00     0.01     0.01
#> tau_alpha1       0.06    0.01    0.14     0.00     0.00     0.00     0.03
#> tau_alpha2       0.57    0.18    1.16     0.00     0.00     0.04     0.48
#> tau_alpha3       0.16    0.05    0.37     0.00     0.00     0.01     0.10
#> mu_alpha1        0.60    2.16   44.78   -96.97   -11.21     0.07    12.31
#> mu_alpha2       -0.23    1.75   28.44   -60.60    -2.53     0.28     3.26
#> mu_alpha3        4.83    3.07   45.34   -94.43    -4.41     0.46    12.48
#> sigma_alpha1    96.57   17.94  345.42     1.34     5.42    18.80    58.05
#> sigma_alpha2    53.34   10.72  383.00     0.49     1.44     5.24    24.32
#> sigma_alpha3   136.93   49.26 1201.90     0.90     3.19    14.13    51.62
#> lp__         -2535.56    0.29    3.56 -2542.88 -2538.01 -2535.34 -2532.97
#>                 97.5% n_eff Rhat
#> alpha1           0.15    43 1.04
#> alpha2           0.22    41 1.02
#> alpha3           0.02   245 1.00
#> tau_alpha1       0.56   197 1.00
#> tau_alpha2       4.23    42 1.00
#> tau_alpha3       1.23    47 1.00
#> mu_alpha1      109.84   431 1.02
#> mu_alpha2       57.56   263 1.00
#> mu_alpha3      107.19   218 1.00
#> sigma_alpha1   676.53   371 1.00
#> sigma_alpha2   324.42  1276 1.00
#> sigma_alpha3   791.76   595 1.00
#> lp__         -2529.63   149 1.01
#> 
#> Samples were drawn using NUTS(diag_e) at Tue Jul 28 14:55:01 2026.
#> For each parameter, n_eff is a crude measure of effective sample size,
#> and Rhat is the potential scale reduction factor on split chains (at 
#> convergence, Rhat=1).
plot(model)

# }