Fits a segmented quasi-Poisson regression to estimate the immediate and sustained effects of one or more interruptions (policies, extreme events, pandemics) on a daily health outcome count series. The model decomposes each interruption into a level change (immediate step) and a slope change (sustained trend shift), controlling for the underlying time trend and seasonal variation via harmonic terms. A counterfactual projection shows what would have been expected had the interruption not occurred.
Usage
sus_mod_its(
data,
outcome_col = "n_obitos",
date_col = "date",
interruption_dates,
harmonics = 2L,
family = "quasipoisson",
covariates = NULL,
alpha = 0.05,
counterfactual = TRUE,
lang = "pt",
verbose = TRUE
)Arguments
- data
A
climasus_dfat stage"aggregate"or"climate", or anydata.framewith a date column and an integer count column.- outcome_col
Character. Name of the daily health outcome count column. Default:
"n_obitos".- date_col
Character. Name of the date column. Default:
"date".- interruption_dates
Date or character vector of at least one interruption date (ISO
"YYYY-MM-DD"format). Must lie strictly within the data range. For a single interruption pass a scalar; for multiple, pass a vector.- harmonics
Integer. Number of sinusoidal harmonic pairs for seasonal control (\(H\) in the model above).
0suppresses seasonal terms. Default:2L.- family
Character. GLM family:
"quasipoisson"(default, robust to overdispersion) or"poisson".- covariates
Character vector or
NULL. Names of additional columns to include as linear confounders (e.g.,"rh_pct","holiday"). Must be numeric or dummy-coded. Default:NULL.- alpha
Numeric. Significance level for confidence intervals. Default:
0.05(95% CI).- counterfactual
Logical. Compute and return counterfactual predictions. Default:
TRUE.- lang
Character. Language for messages:
"pt"(default),"en","es".- verbose
Logical. Print progress messages. Default
TRUE.
Value
A climasus_its list with:
$modelThe fitted
glmobject.$effectsTibble with one row per interruption:
label,interruption_date,level_ratio,level_ci_lo,level_ci_hi,level_p,slope_daily_log,slope_ratio_annual,slope_p.$counterfactualTibble with daily
date,observed,predicted(fitted values),counterfactual,cf_lo,cf_hi,ratio_to_cf,prevented.NULLwhencounterfactual = FALSE.$segmentsTibble with one row per segment (pre-interruption and each post-interruption interval):
segment,start_date,end_date,n_days,mean_observed,mean_predicted,mean_counterfactual.$dataThe analysis dataset with all model covariates.
$metaAnalysis parameters and diagnostics.
Statistical framework
For \(K\) interruption dates \(T_1 < T_2 < \ldots < T_K\), the segmented Poisson GLM is:
$$\log(E[Y_t]) = \beta_0 + \beta_1 t + \sum_{j=1}^{K}\left[\beta_{2j}\, D_j(t) + \beta_{2j+1}\, S_j(t)\right] + \sum_{k=1}^{H}\left[\gamma_k \sin\!\left(\tfrac{2\pi k\, t}{365.25}\right) + \delta_k \cos\!\left(\tfrac{2\pi k\, t}{365.25}\right)\right] + \mathbf{z}_t^\top \boldsymbol{\eta}$$
where \(D_j(t) = \mathbf{1}(t \ge T_j)\) is the step indicator and \(S_j(t) = \max(0,\, t - T_j)\) is the slope-change ("hockey stick") basis. The immediate rate ratio at interruption \(j\) is \(RR_j = e^{\beta_{2j}}\); the sustained trend shift is \(e^{\beta_{2j+1}}\) per day (or \(e^{365.25\,\beta_{2j+1}}\) per year).
Counterfactual
The counterfactual is the model prediction with all \(D_j\) and \(S_j\)
set to zero — i.e., the pre-interruption baseline trend projected forward
through the study period. The difference observed - counterfactual is the
estimated total attributable change.
References
Bernal, J.L., Cummins, S., & Gasparrini, A. (2017). Interrupted time series regression for the evaluation of public health interventions: a tutorial. International Journal of Epidemiology, 46(1), 348-355. doi:10.1093/ije/dyw098
Penfold, R.B., & Zhang, F. (2013). Use of interrupted time series analysis in evaluating health care quality improvements. Academic Pediatrics, 13(6 Suppl), S38-44. doi:10.1016/j.acap.2013.08.002
Examples
if (FALSE) { # \dontrun{
# Single interruption (COVID-19 pandemic onset)
its <- sus_mod_its(
df_daily,
outcome_col = "n_obitos",
interruption_dates = "2020-03-17",
harmonics = 2L,
lang = "pt"
)
print(its)
tidy(its)
# Multiple interruptions
its2 <- sus_mod_its(
df_daily,
outcome_col = "n_obitos",
interruption_dates = c("2020-03-17", "2021-01-18"),
lang = "en"
)
} # }
