Skip to contents

Fits a time-stratified case-crossover model to quantify the association between a climate exposure and a daily health outcome. Each time stratum (month or week) acts as its own control, removing long-term trends and seasonal confounding by design. Two fitting methods are supported: "conditional_poisson" (GLM with stratum fixed effects, default) for aggregate count data, and "clogit" (conditional logistic regression) for binary outcomes or rare events.

Usage

sus_mod_casecrossover(
  data,
  outcome_col = "n_obitos",
  exposure_col,
  covariates = NULL,
  stratum = "month",
  lag = 0L,
  method = "conditional_poisson",
  family = "quasipoisson",
  alpha = 0.05,
  lang = "pt",
  verbose = TRUE
)

Arguments

data

A climasus_df at stage "aggregate" or "climate" (produced by sus_climate_aggregate()), or any data.frame containing at minimum a date column (Date), an outcome count column, and an exposure column.

outcome_col

Character. Name of the daily health outcome count column (e.g., "n_obitos", "n_internacoes"). Default: "n_obitos".

exposure_col

Character. Name of the exposure column. Required; no auto-detection is performed (unlike sus_mod_dlnm()). Examples: "tair_dry_bulb_c", "pm25_mean", "precip_mm".

covariates

Character vector or NULL. Names of additional columns to include as linear confounders. These should be time-varying within strata (e.g., day-of-week dummy, holiday indicator, relative humidity). Long-term trends are already controlled by the strata. Default: NULL.

stratum

Character. Time stratum type or name of an existing column:

  • "month" (default): year-month strata (e.g., "2021-07").

  • "week": ISO year-week strata (e.g., "2021-W27").

  • Any column name in data: uses that column's values as stratum IDs.

lag

Integer or integer vector. Lag(s) to apply to the exposure before fitting. A single integer uses that specific lag; a vector uses the mean of exposures at all specified lags. Default: 0L (same-day exposure).

method

Character. Fitting method:

  • "conditional_poisson" (default): GLM with stratum fixed effects. Preferred for aggregate count data; uses stats::glm() with the specified family.

  • "clogit": conditional logistic regression via survival::clogit(). Requires the survival package. Treats outcome as binary (is_case = count > 0); best for rare events.

family

Character. GLM family for method = "conditional_poisson": "quasipoisson" (default, robust to overdispersion) or "poisson". Ignored for method = "clogit".

alpha

Numeric. Significance level for confidence intervals. Default: 0.05 (95% CI).

lang

Character. Language for messages: "pt" (default), "en", "es".

verbose

Logical. Print progress messages. Default TRUE.

Value

A climasus_casecrossover list with:

$model

The fitted model object: a glm for "conditional_poisson" or a clogit object for "clogit".

$or_table

Tibble with one row per exposure term: term, lag_spec, estimate (log-OR), or, or_lo, or_hi, p_value.

$data

The analysis dataset after lag creation and NA removal: columns date, outcome_val, exposure_val, stratum_id, and any covariates.

$diagnostics

List: n_obs, n_cases, n_strata, disp_ratio (for "conditional_poisson"), method, family.

$meta

List of analysis parameters: outcome_col, exposure_col, covariates, stratum, lag, method, family, alpha, call_time.

Statistical framework

"conditional_poisson" method (Whitaker et al., 2006):

$$\log(E[Y_t]) = \alpha_s + \beta X_t + \mathbf{z}_t^\top \boldsymbol{\gamma}$$

where \(\alpha_s\) is a stratum-specific intercept (absorbed as factor(stratum_id) in the GLM), \(X_t\) is the (possibly lagged or averaged) exposure on day \(t\), and \(\mathbf{z}_t\) are optional time-varying covariates. The rate ratio is \(RR = e^\beta\).

"clogit" method (Maclure, 1991; Levy et al., 2001):

Uses survival::clogit() with the binary indicator \(D_t = \mathbf{1}(Y_t > 0)\) as the outcome. Each case day is matched to all other days within the same stratum as controls. This method is most appropriate for rare events (low daily counts) and binary outcomes.

Lag specification

The lag argument controls how the daily exposure is lagged before the association is estimated:

  • Single integer (e.g., lag = 0): uses the exposure exactly lag days before the outcome day.

  • Integer vector (e.g., lag = 0:6): uses the arithmetic mean of exposures at all specified lags — a moving average common for temperature (e.g., lag = 0:6 is the "lag 0-6" or "mean temperature over 7 days").

References

Maclure, M. (1991). The case-crossover design: a method for studying transient effects on the risk of acute events. American Journal of Epidemiology, 133(2), 144-153. doi:10.1093/oxfordjournals.aje.a115853

Levy, D., Lumley, T., Sheppard, L., Kaufman, J., & Checkoway, H. (2001). Referent selection in case-crossover analyses of acute health effects of air pollution. Epidemiology, 12(2), 186-192.

Whitaker, H.J., Farrington, C.P., Spiessens, B., & Musonda, P. (2006). Tutorial in biostatistics: the self-controlled case series method. Statistics in Medicine, 25(10), 1768-1797. doi:10.1002/sim.2302

Armstrong, B.G., Gasparrini, A., & Tobias, A. (2014). Conditional Poisson models: a flexible alternative to conditional logistic case crossover analysis. BMC Medical Research Methodology, 14, 122. doi:10.1186/1471-2288-14-122

Examples

if (FALSE) { # \dontrun{
# Conditional Poisson with lag-0 temperature
cc <- sus_mod_casecrossover(
  df_daily,
  outcome_col  = "n_obitos",
  exposure_col = "tair_dry_bulb_c",
  stratum      = "month",
  lag          = 0L,
  lang         = "pt"
)
print(cc)
tidy(cc)

# Moving-average lag 0-6
cc_lag06 <- sus_mod_casecrossover(
  df_daily,
  outcome_col  = "n_obitos",
  exposure_col = "tair_dry_bulb_c",
  lag          = 0L:6L,
  lang         = "en"
)
} # }