
Modelado 03: Case-Crossover y Series Temporales Interrumpidas
Equipo climasus4r
17/10/2026
Source:vignettes/mod-03-crossover-its.Rmd
mod-03-crossover-its.RmdObjetivo
Al final de este tutorial usted será capaz de:
- Ajustar un Case-Crossover estratificado por tiempo
(
sus_mod_casecrossover()) para cuantificar la asociación entre temperatura y muertes respiratorias, controlando la confusión estacional y de largo plazo por diseño. - Comparar especificaciones de rezago (lag-0 y lag 0-6) y métodos de ajuste (Poisson condicional vs. clogit).
- Ajustar una Serie Temporal Interrumpida
(
sus_mod_its()) para estimar efectos inmediatos y tendencias después de una fecha de interrupción, con contrafactual proyectado. - Visualizar e interpretar los resultados con
sus_mod_plot_its().
Estos enfoques completan el repertorio de análisis de series temporales en epidemiología ambiental, complementando el DLNM (Tutorial Modelado 01) y la fracción atribuible (Tutorial Modelado 02).
Contexto científico
Case-Crossover
El diseño case-crossover (Maclure, 1991) fue creado para estudiar exposiciones transitorias y desenlaces agudos. Cada individuo (o día-desenlace) funciona como su propio control: la exposición en el día del evento se compara con la exposición en días de referencia dentro del mismo estrato temporal. Esto elimina, por construcción, todos los factores de confusión que varían lentamente — estacionalidad, tendencias de largo plazo, factores socioeconómicos estables.
La versión estratificada por tiempo (Levy et al.,
2001; Armstrong et al., 2014) agrupa los controles dentro de meses o
semanas (estratos año-mes en climasus4r), haciendo que el
estimador sea equivalente a una Poisson condicional con
efectos fijos de estrato. Los efectos fijos de estrato absorben toda la
variación entre meses y años — estacionalidad anual, tendencia de largo
plazo, factores socioeconómicos estables — pero los factores de
confusión que varían dentro del mismo mes (ej.: días festivos,
humedad relativa) deben ajustarse explícitamente mediante
covariates. Para datos de conteo agregados (series diarias
de muertes por municipio), el método de Poisson
Condicional es preferible al clogit (Armstrong et al.,
2014).
IRR vs. OR: En el método
"conditional_poisson", el coeficiente estimado es un IRR (Incidence Rate Ratio) — razón de tasas de incidencia. Bajo el supuesto de evento raro, IRR ≈ OR. En el método"clogit", el estimador es un OR estricto.climasus4rusa los campos$or_table,or,or_lo,or_hipara ambos métodos por uniformidad; interprete como IRR cuandomethod = "conditional_poisson"y como OR cuandomethod = "clogit".
Serie Temporal Interrumpida (ITS)
El análisis de series temporales interrumpidas (Bernal et al., 2017) evalúa el impacto causal de una intervención o evento sobre una serie de conteos. El modelo segmentado estima dos componentes para cada interrupción:
- Cambio de nivel (level change): efecto inmediato en el período posterior.
- Cambio de tendencia (slope change): desviación sostenida en la trayectoria después de la interrupción.
El contrafactual es la proyección de la tendencia previa a la interrupción hacia el período posterior, permitiendo estimar cuántos eventos fueron prevenidos (o excedidos) por la interrupción.
Caso conductor. Investigamos la asociación entre temperatura y muertes respiratorias en adultos mayores (60+) en la Región Metropolitana de São Paulo, 2014–2019 (CIE-10: J00–J99). En el case-crossover, estimamos el IRR por 1 °C de temperatura (lag-0 y lag 0-6; Poisson condicional). En el ITS, usamos octubre de 2014 como fecha de interrupción hipotética — representando un episodio de anomalía climática — para demostrar la detección de cambios abruptos en series de salud.
Datos utilizados
| Dato | Archivo | Columnas clave | Origen |
|---|---|---|---|
| Serie diaria de muertes, RMSP |
dados/caso_serie.rds ($serie_diaria) |
date, n_obitos
|
SIM-DO (Tutorial 1–4) |
| Temperatura diaria INMET | dados/caso_clima_estacao.rds |
date, tair_dry_bulb_c
|
Tutorial 7 |
Los datos son cargados por el script de pre-renderización. Si los archivos no existen, el script sintetiza una serie mínima realista con una advertencia explícita — el tutorial se renderiza sin errores, pero los resultados numéricos no deben usarse para publicación.
Pipeline completo
library(climasus4r)
library(dplyr)
# tidy() é fornecido pelo pacote 'generics' (re-exportado pelo climasus4r)
# Se não estiver disponível via climasus4r, carregue: library(generics)Cargar y preparar los datos
# Série de óbitos (caso_serie.rds gerado pelo Tutorial 4)
# Caminhos relativos ao diretório da vignette (vignettes-pt/)
raw_serie <- readRDS("dados/caso_serie.rds")
df_serie <- raw_serie$serie_diaria |>
group_by(date) |>
summarise(n_obitos = sum(n_obitos, na.rm = TRUE), .groups = "drop") |>
mutate(date = as.Date(date))
# Temperatura INMET (caso_clima_estacao.rds gerado pelo Tutorial 7)
df_clima <- readRDS("dados/caso_clima_estacao.rds") |>
group_by(date) |>
summarise(tair_dry_bulb_c = mean(tair_dry_bulb_c, na.rm = TRUE),
.groups = "drop") |>
mutate(date = as.Date(date))
# Junção série + clima
df_joint <- inner_join(df_serie, df_clima, by = "date")Case-Crossover — Lag-0
cc0 <- sus_mod_casecrossover(
data = df_joint,
outcome_col = "n_obitos",
exposure_col = "tair_dry_bulb_c",
stratum = "month", # estratos = ano-mês (e.g. "2014-10")
lag = 0L, # temperatura do mesmo dia
method = "conditional_poisson",
family = "quasipoisson", # robusto à superdispersão
alpha = 0.05,
lang = "pt"
)
print(cc0)
tidy(cc0) # tibble com IRR (campos: or/or_lo/or_hi), IC95%, p-valor
# Nota: para method="conditional_poisson", o estimador é o IRR (Incidence Rate Ratio),
# equivalente ao RR sob a hipótese de evento raro. Os campos chamam-se or/or_lo/or_hi
# por uniformidade com o método clogit (que retorna OR estrito).Case-Crossover — Lag 0-6 (media móvil)
cc06 <- sus_mod_casecrossover(
data = df_joint,
outcome_col = "n_obitos",
exposure_col = "tair_dry_bulb_c",
stratum = "month",
lag = 0L:6L, # média da temperatura dos últimos 7 dias
method = "conditional_poisson",
family = "quasipoisson",
alpha = 0.05,
lang = "pt"
)
print(cc06)Case-Crossover — clogit (opcional)
# Requer o pacote 'survival'. Trata o desfecho como binário (is_case = count > 0).
# Adequado para eventos raros; para séries de contagem diária, prefira
# method = "conditional_poisson" (Armstrong et al., 2014).
if (requireNamespace("survival", quietly = TRUE)) {
cc_clogit <- sus_mod_casecrossover(
data = df_joint,
outcome_col = "n_obitos",
exposure_col = "tair_dry_bulb_c",
stratum = "month",
lag = 0L,
method = "clogit",
alpha = 0.05,
lang = "pt"
)
print(cc_clogit)
}Serie Temporal Interrumpida
its1 <- sus_mod_its(
data = df_joint,
outcome_col = "n_obitos",
date_col = "date",
interruption_dates = as.Date("2014-10-01"), # data de interrupção
harmonics = 2L, # 2 pares de harmônicos (sazonalidade)
family = "quasipoisson",
covariates = NULL,
alpha = 0.05,
counterfactual = TRUE, # projeta tendência pré para comparação
lang = "pt"
)
print(its1)
tidy(its1) # tibble: efeito imediato + tendência por interrupção
its1$segments # média diária por segmento (pré / pós)
its1$counterfactual # série: observado, ajustado, contrafactual, prevenidosVisualización con sus_mod_plot_its()
Nota de implementación:
sus_mod_plot_its()es la función de visualización pareada asus_mod_its(). Los bloques a continuación documentan la API planeada (eval = FALSE). Las figuras en los resultados ilustrados fueron generadas con ggplot2 directamente en el script de pre-renderización. Cuando la función esté disponible en el paquete, sustituya los bloques del script por el patrón indicado a continuación.
# Tipo "series": série observada, ajustada e contrafactual com IC
p_serie <- sus_mod_plot_its(
fit = its1,
type = "series",
output_type = "plot",
lang = "pt"
)
p_serie
# Tipo "effects": floresta de RR de nível e tendência por interrupção
p_effects <- sus_mod_plot_its(
fit = its1,
type = "effects",
output_type = "plot",
lang = "pt"
)
p_effects
# Tipo "segments": barras comparativas por segmento
p_segs <- sus_mod_plot_its(
fit = its1,
type = "segments",
output_type = "plot",
lang = "pt"
)
p_segs
# Tipo "prevented": série de eventos prevenidos (ou excedentes)
p_prev <- sus_mod_plot_its(
fit = its1,
type = "prevented",
output_type = "plot",
lang = "pt"
)
p_prev
# output_type = "table": retorna tibble com os dados do gráfico
tbl_cf <- sus_mod_plot_its(
fit = its1,
type = "series",
output_type = "table",
lang = "pt"
)
head(tbl_cf)Características de las funciones
sus_mod_casecrossover()
Función de modelado para case-crossover estratificado por tiempo.
Acepta climasus_df o data.frame con columnas
date, desenlace y exposición. Devuelve un objeto
climasus_casecrossover.
| Argumento | Predeterminado | Descripción |
|---|---|---|
data |
— |
climasus_df (stage "aggregate" o
"climate") o data.frame
|
outcome_col |
"n_obitos" |
Nombre de la columna de conteo del desenlace |
exposure_col |
(obligatorio) | Nombre de la columna de exposición (ej.:
"tair_dry_bulb_c", "pm25_mean") |
covariates |
NULL |
Factores de confusión adicionales que varían dentro del estrato |
stratum |
"month" |
Tipo de estrato temporal: "month" (estratos año-mes,
e.g. "2014-10"), "week" (semana ISO), o nombre
de columna existente para estratos personalizados |
lag |
0L |
Rezago(s) aplicados a la exposición; vector = media de los lags especificados |
method |
"conditional_poisson" |
"conditional_poisson" (GLM con
factor(stratum_id)) o "clogit"
(survival::clogit()) |
family |
"quasipoisson" |
Familia GLM para conditional_poisson; ignorado en
clogit
|
alpha |
0.05 |
Nivel de significancia para el IC |
lang |
"pt" |
Idioma de los mensajes ("pt", "en",
"es") |
verbose |
TRUE |
Muestra el progreso |
Retorno — climasus_casecrossover:
| Campo | Contenido |
|---|---|
$model |
Objeto glm (conditional_poisson) o clogit
(survival) |
$or_table |
Tibble: term, lag_spec,
estimate (log-IRR para conditional_poisson,
log-OR para clogit), or, or_lo,
or_hi, p_value
|
$data |
Conjunto de análisis: date, outcome_val,
exposure_val, stratum_id, covariables |
$diagnostics |
n_obs, n_cases, n_strata,
disp_ratio, method, family
|
$meta |
Parámetros de llamada: outcome_col,
exposure_col, stratum, lag,
etc. |
Métodos S3 disponibles: print(),
summary(), tidy() (devuelve
$or_table con metadatos con prefijo, adecuado para
bind_rows() entre ciudades).
sus_mod_its()
Análisis de series temporales interrumpidas mediante regresión de
Poisson segmentada. Admite múltiples interrupciones y contrafactual.
Devuelve un objeto climasus_its.
| Argumento | Predeterminado | Descripción |
|---|---|---|
data |
— |
climasus_df o data.frame con columnas de
fecha y conteo |
outcome_col |
"n_obitos" |
Columna de desenlace |
date_col |
"date" |
Columna de fecha |
interruption_dates |
(obligatorio) | Fecha(s) de interrupción (ISO "YYYY-MM-DD"); escalar o
vector |
harmonics |
2L |
Número de pares de armónicos estacionales ( en la ecuación) |
family |
"quasipoisson" |
Familia GLM: "quasipoisson" o
"poisson"
|
covariates |
NULL |
Factores de confusión adicionales (ej.: "rh_pct",
"holiday") |
alpha |
0.05 |
Nivel de significancia |
counterfactual |
TRUE |
Calcular y devolver el contrafactual |
lang |
"pt" |
Idioma de los mensajes |
verbose |
TRUE |
Muestra el progreso |
Retorno — climasus_its:
| Campo | Contenido |
|---|---|
$model |
Objeto glm
|
$effects |
Tibble por interrupción: label,
interruption_date, level_ratio,
level_ci_lo, level_ci_hi,
level_p, slope_daily_log,
slope_ratio_annual, slope_p
|
$counterfactual |
Tibble diario: date, observed,
predicted, counterfactual, cf_lo,
cf_hi, ratio_to_cf,
prevented
|
$segments |
Tibble por segmento: segment, start_date,
end_date, n_days, mean_observed,
mean_predicted, mean_counterfactual
|
$data |
Conjunto de datos con todas las covariables del modelo |
$meta |
Parámetros y diagnósticos: n_obs, n_pre,
disp_ratio, interruption_dates, etc. |
Métodos S3 disponibles: print(),
summary(), tidy() (devuelve
$effects con metadatos, ideal para combinar múltiples
ciudades con bind_rows()).
sus_mod_plot_its()
Estado: función planeada para
climasus4r. La API a continuación documenta la especificación completa. Las figuras de este tutorial fueron generadas mediante ggplot2 directamente en el script de pre-renderización (scripts/modelagem_03_crossover_its.R); cuandosus_mod_plot_its()esté disponible, sustituirá ese código.
Visualización pareada del objeto climasus_its. Todos los
type= operan sobre los mismos datos internos — elija según
el aspecto del modelo que desee comunicar.
type = |
Qué muestra | Tabla devuelta |
|---|---|---|
"series" |
Serie temporal completa con observado, ajustado y contrafactual (IC) + línea de interrupción | Tibble con columnas del $counterfactual
|
"effects" |
Gráfico de bosque (forest plot) de RR de nivel y cambio de tendencia por interrupción | Tibble con $effects formateado |
"segments" |
Barras comparativas de las medias observado/ajustado/contrafactual por segmento | Tibble con $segments en formato largo |
"prevented" |
Serie de eventos prevenidos (o excedentes) = contrafactual − observado | Tibble con fecha y prevenidos acumulados |
Argumento output_type: -
"plot" (predeterminado): devuelve objeto
ggplot2. - "table": devuelve tibble. -
"all": devuelve lista
list(plot = ..., table = ...).
Argumento interactive = TRUE: convierte
el gráfico a plotly (requiere plotly
instalado).
Formulación matemática
Case-Crossover (Poisson Condicional)
donde
es el intercepto del estrato
(absorbido como factor(stratum_id) en el GLM),
es la exposición en el día
con rezago
(o la media aritmética de los lags
cuando lag es un vector), y
son covariables que varían dentro del estrato. La razón
de tasas de incidencia (Incidence Rate Ratio) es:
En el método "clogit" (Maclure, 1991), el desenlace es
el indicador binario
y el modelo de Cox condicional se ajusta con
survival::clogit(), produciendo una razón de
momios (odds ratio,
).
Para series de conteo con desenlace frecuente, prefiera
"conditional_poisson", ya que el OR sobreestima el IRR
cuando el evento no es raro (Armstrong et al., 2014).
Serie Temporal Interrumpida
Para fechas de interrupción , el modelo segmentado es:
donde es el indicador de nivel (step) y es el término de pendiente (slope change / “hockey stick”).
| Parámetro | Interpretación |
|---|---|
| RR inmediato (cambio de nivel) en la interrupción | |
| RR de tendencia por día después de la interrupción | |
| RR de tendencia anualizado |
El contrafactual es la predicción del modelo con para todo — es decir, la proyección de la tendencia previa a la interrupción hacia el período posterior.
Resultados ilustrados
Tabla 1. IRR de la Temperatura sobre Muertes Respiratorias (Case-Crossover)
| especificacao | lag_spec | or | or_lo | or_hi | p_value |
|---|---|---|---|---|---|
| Lag 0 | 0 | 0.9928 | 0.9770 | 1.0088 | 0.377 |
| Lag 0-6 (media) | 0-6 | 1.0032 | 0.9714 | 1.0360 | 0.847 |
Figura 1. IRR por Especificación de Rezago (Bosque)

Figura 1. IRR (Incidence Rate Ratio) de la temperatura (por 1 °C) sobre muertes respiratorias diarias en la RMSP, comparando lag-0 (temperatura del mismo día) y lag 0-6 (media de los últimos 7 días). Poisson condicional (quasipoisson), estratificado por año-mes. IC: 95%.
Figura 2. IRR por Rezago Individual (Lag 0 a 6)

Figura 2. IRR de la temperatura para cada rezago individual (lag 0 a 6 días). Cada punto representa un modelo case-crossover independiente con lag fijo (Poisson condicional, quasipoisson). La curva revela el perfil temporal de la asociación exposición-respuesta.
Figura 3. ITS — Serie Observada, Ajustada y Contrafactual

Figura 3. Serie temporal de muertes respiratorias diarias en la RMSP (gris: observado; verde: ajustado por el modelo ITS; naranja discontinuo: contrafactual con IC 95%). La línea punteada vertical indica la fecha de interrupción (01/10/2014). La separación entre ajustado y contrafactual mide el efecto atribuible a la interrupción.
Figura 4. ITS — Efecto Inmediato (Bosque)

Figura 4. RR de nivel (cambio inmediato) estimado por el modelo ITS para la interrupción del 01/10/2014. RR > 1 indica aumento de muertes; RR < 1, reducción. IC: 95%.
Tabla 2. Efectos del Modelo ITS
| label | interruption_date | level_ratio | level_ci_lo | level_ci_hi | level_p | slope_daily_log | slope_ratio_annual | slope_p |
|---|---|---|---|---|---|---|---|---|
| Interruption 1 | 2014-10-01 | 1.0115 | 0.8694 | 1.1767 | 0.883 | 0.0004293 | 1.1698 | 0.421 |
Figura 5. ITS — Medias por Segmento

Figura 5. Media diaria de muertes respiratorias por segmento (pre- y post-interrupción). Tres barras por segmento: observado, ajustado por el modelo y contrafactual (proyección de la tendencia previa a la interrupción).
Figura 6. ITS — Eventos Prevenidos (o Excedentes) Diarios

Figura 6. Serie diaria de eventos prevenidos (contrafactual −
observado). Los valores positivos indican reducción de muertes
atribuible a la interrupción; los valores negativos indican exceso. La
línea horizontal en cero es la referencia de ningún efecto. Corresponde
al campo prevented de
$counterfactual.
Referencias
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. https://doi.org/10.1186/1471-2288-14-122
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. https://doi.org/10.1093/ije/dyw098
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.
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. https://doi.org/10.1093/oxfordjournals.aje.a115853
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. https://doi.org/10.1016/j.acap.2013.08.002
Saldanha, R.F., Bastos, R.R., & Barcellos, C. (2019). Microdatasus: pacote para download e pré-processamento de microdados do DataSUS. Cadernos de Saúde Pública, 35(9), e00032419. https://doi.org/10.1590/0102-311X00032419
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. https://doi.org/10.1002/sim.2302
Navegación
| Anterior | Modelado 02: Fracción Atribuible |
| Siguiente | Modelado 04: Multiciudad y Metaanálisis |
| Hub | Todos los tutoriales |