Skip to contents

Introducción

Tutorial Completo — Este tutorial abarca desde las estrategias temporales básicas hasta las más avanzadas de la función sus_climate_aggregate(), el motor matemático y epidemiológico de climasus4r responsable de alinear datos de salud (DATASUS) con series temporales meteorológicas (INMET).

Entradas de la Función (Inputs)

Para que la integración ocurra, necesita proporcionar dos objetos climasus_df listos:

Argumento Descripción Requisito de stage en los Metadatos
health_data Datos de salud de DATASUS ya agregados espacialmente. Debe estar en la etapa "spatial" (salida de sus_spatial_join()).
climate_data Datos meteorológicos del INMET sin fallas. Debe estar en la etapa "climate" (salida de sus_climate_inmet() y/o sus_climate_fill()).
climate_var Qué variables climáticas tomar (ej.: "tair_dry_bulb_c", "rainfall_mm"). Predeterminado: "all". -
temporal_strategy Una de las 10 estrategias detalladas en el tutorial anterior. -
climate_region "auto", "tropical", "subtropical", o "temperate". Adapta parámetros automáticamente. -
window_days Entero. Necesario para moving_window, degree_days, y estrategias de excedencia/pesos. -
lag_days Entero (o vector). Necesario para discrete_lag y distributed_lag. -
offset_days Vector de 2 enteros (ej.: c(7, 14)). Necesario para offset_window. -

Atención: La función abortará con mensajes en portugués, inglés o español (parámetro lang) si los metadatos indican que los datos no pasaron por las etapas correctas del pipeline. Esto evita sesgos silenciosos en su análisis.


Parte 1: Preparación de los Datos de Salud (SIM-DO)

1.1 Importación y Limpieza de los Datos de Defunción

El pipeline a continuación procesa datos del Sistema de Información sobre Mortalidad (SIM) para el estado de Amazonas en el año 2023.

# ============================================================================
# PIPELINE COMPLETO DE PROCESAMIENTO DE LOS DATOS DE SALUD
# ============================================================================
library(climasus4r)
df_sim <- sus_data_import(
  uf = "AM",                    # Amazonas
  year = 2023,                  # Año completo
  system = "SIM-DO",            # SIM Declaración de Defunción
  use_cache = TRUE,             # Usar caché para evitar re-descarga
  verbose = TRUE
) |>
  # Limpieza de encoding (acentos, caracteres especiales)
  sus_data_clean_encoding() |>

  # Estandarización de columnas (nombres, tipos, formatos)
  sus_data_standardize(lang = "pt") |>

  # Filtro por CID - enfermedades respiratorias (J00-J99)
  sus_data_filter_cid(disease_group = "respiratory") |>

  # Creación de variables derivadas
  sus_data_create_variables(
    create_age_groups = TRUE,                    # Grupos etarios
    age_breaks = c(60, 70, 80, 90, Inf),        # Rangos para adultos mayores
    age_labels = c("60-69", "70-79", "80-89", "90+"),
    create_calendar_vars = TRUE,                 # Mes, semana, día de la semana
    create_climate_vars = TRUE,                  # Variables climáticas derivadas
    climate_region = "Norte",                    # Región Norte de Brasil
    lang = "pt"
  ) |>

  # Filtros demográficos
  sus_data_filter_demographics(
    sex = c("Masculino", "Feminino"),            # Ambos sexos
    age_range = c(65, Inf)                       # Solo adultos mayores (65+)
  ) |>

  # Agregación temporal (diaria)
  sus_data_aggregate(
    date_col = NULL,              # Usa la fecha de defunción automáticamente
    complete_dates = FALSE,       # No completar fechas faltantes
    time_unit = "day",            # Agregación diaria
    lang = "pt"
  )

# Visualizar metadatos del objeto
sus_meta(df_sim)

# Resumen estadístico
summary(df_sim)

Interpretación de los Resultados: - El objeto df_sim contiene el conteo diario de defunciones por enfermedades respiratorias - Población objetivo: adultos mayores (65+ años) en Amazonas - Período: 1 de enero a 31 de diciembre de 2023

Parte 2: Agregación Espacial

2.1 Join Espacial con Malla Municipal

La función sus_spatial_join() asigna a cada defunción las coordenadas geográficas del municipio de ocurrencia.

# ============================================================================
# AGREGACIÓN ESPACIAL A NIVEL MUNICIPAL
# ============================================================================

sf_sim_spatial <- sus_spatial_join(
  df = df_sim,
  level = "munic",              # Nivel municipal (vs. "state" o "health_region")
  lang = "pt"
)

# Verificar metadatos (ahora con componente espacial)
sus_meta(sf_sim_spatial)

Nota: El objeto ahora es un sf (simple features) con geometría de los municipios.


Parte 3: Datos Climáticos (INMET)

3.1 Descarga, Preprocesamiento y Relleno de fallas

Descargamos datos meteorológicos de las estaciones del INMET en Amazonas.

# ============================================================================
# DESCARGA DE LOS DATOS DEL INMET
# ============================================================================

df_inmet_raw <- sus_climate_inmet(
  years = 2023,                 # Mismo año que los datos de salud
  uf = "AM"                     # Solo estaciones en Amazonas
)

# Verificar estaciones descargadas
unique(df_inmet_raw$station_name)

# ============================================================================
# IMPUTACIÓN DE DATOS FALTANTES
# ============================================================================

df_inmet <- sus_climate_fill_inmet(
  df_inmet_raw,
  target_var = "all",           # Imputar todas las variables climáticas
  parallel = TRUE,              # Procesamiento paralelo (más rápido)
  run_evaluation = FALSE        # Omitir evaluación detallada
)

# Para acelerar los ejemplos, podemos guardar/leer los datos procesados en el formato ultra rápido parquet
# sus_data_export(df_inmet, "df_inmet_AM_2023_filled.parquet")
# sus_data_export(sf_sim_spatial, "df_sim_AM_2023_spatial.parquet")

# Cargar datos preprocesados (si está disponible)
# df_inmet <- sus_data_read("df_inmet_AM_2023_filled.parquet")
# sf_sim_spatial <- sus_data_read("df_sim_AM_2023_spatial.parquet")

Parte 4: Estrategias de Agregación Climática con sus_climate_aggregate()

4.1 Estrategia Exact (Coincidencia Exacta)

Objetivo: Asociar la temperatura del mismo día de la defunción. Aplicación: Eventos agudos como hipertermia, ACV, infarto.

# ============================================================================
# EXACT: Temperatura del mismo día
# ============================================================================

df_exact <- sus_climate_aggregate(
  health_data = sf_sim_spatial,
  climate_data = df_inmet,
  climate_var = "tair_dry_bulb_c",      # Temperatura de bulbo seco (°C)
  temporal_strategy = "exact",
  lang = "pt",
  verbose = TRUE
)

# Verificar nueva columna
names(df_exact)
summary(df_exact$tair_dry_bulb_c)

# Análisis rápido: relación entre temperatura y defunciones
library(ggplot2)
df_exact %>%
    ggplot(aes(x = tair_dry_bulb_c, y = n_obitos)) +
    geom_point(alpha = 0.5) +
    geom_smooth(method = "loess", color = "red") +
    labs(
      title = "Relación entre Temperatura y Defunciones (Mismo Día)",
      x = "Temperatura (°C)",
      y = "Número de Defunciones"
    ) +
    theme_minimal()

Variables del INMET Soportadas Presión Atmosférica: patm_mb (Media), patm_max_mb (Máxima), patm_min_mb (Mínima)

Temperatura del Aire: tair_dry_bulb_c (Bulbo Seco), tair_max_c (Máxima), tair_min_c (Mínima)

Punto de Rocío: dew_tmean_c (Media), dew_tmax_c (Máxima), dew_tmin_c (Mínima)

Humedad Relativa: rh_mean_porc (Media), rh_max_porc (Máxima), rh_min_porc (Mínima)

Viento: ws_2_m_s (Velocidad), ws_gust_m_s (Ráfaga), wd_degrees (Dirección)

Varios: rainfall_mm (Lluvia), sr_kj_m2 (Radiación Solar)

4.2 Estrategia Discrete Lag (Rezago Discreto)

Objetivo: Evaluar el efecto de la temperatura en diferentes rezagos, identificando el período crítico de exposición.

# ============================================================================
# DISCRETE LAG: Temperatura 7, 14 y 21 días antes
# ============================================================================

df_discrete_lag <- sus_climate_aggregate(
  health_data = sf_sim_spatial,
  climate_data = df_inmet,
  climate_var = "tair_dry_bulb_c",
  temporal_strategy = "discrete_lag",
  lag_days = c(7, 14, 21),          # Tres rezagos distintos
  lang = "pt",
  verbose = TRUE
)

# Verificar columnas creadas
names(df_discrete_lag)

# Comparar correlaciones en diferentes rezagos
correlations <- data.frame(
  lag = c(0, 7, 14, 21),
  correlation = c(
    cor(df_exact$tair_dry_bulb_c, df_exact$n_obitos, use = "complete.obs"),
    cor(df_discrete_lag$lag7_tair_dry_bulb_c, df_discrete_lag$n_obitos, use = "complete.obs"),
    cor(df_discrete_lag$lag14_tair_dry_bulb_c, df_discrete_lag$n_obitos, use = "complete.obs"),
    cor(df_discrete_lag$lag21_tair_dry_bulb_c, df_discrete_lag$n_obitos, use = "complete.obs")
  )
)

print(correlations)

Interpretación: Los valores de correlación entre rezago y temperatura son solo ilustrativos y reflejan el período usado en este tutorial.


4.3 Estrategia Distributed Lag (Matriz para DLNM)

Objetivo: Crear una matriz de rezagos para modelos DLNM. Aplicación: Modelado no lineal de efectos rezagados.

# ============================================================================
# DISTRIBUTED LAG: Matriz de rezagos 0 a 21
# ============================================================================

df_distributed <- sus_climate_aggregate(
  health_data = sf_sim_spatial,
  climate_data = df_inmet,
  climate_var = "tair_dry_bulb_c",
  temporal_strategy = "distributed_lag",
  lag_days = 21,                    # Rezago máximo (0 a 21)
  lang = "pt",
  verbose = TRUE
)

# Verificar estructura de la matriz
head(df_distributed)

DLNM: La matriz generada servirá como entrada para el modelo DLNM (paquete dlnm). El climasus4r pondrá a disposición, próximamente, nuevas funcionalidades de modelado y visualización de los resultados.


4.4 Estrategia Moving Window (Ventana Móvil)

Objetivo: Media de la temperatura en los últimos 14 días. Aplicación: Efecto acumulado de exposición prolongada.

# ============================================================================
# MOVING WINDOW: Media de los últimos 14 días
# ============================================================================

df_moving <- sus_climate_aggregate(
  health_data = sf_sim_spatial,
  climate_data = df_inmet,
  climate_var = "tair_dry_bulb_c",
  temporal_strategy = "moving_window",
  window_days = 14,                 # Ventana de 14 días
  min_obs = 0.7,                    # Mínimo de 70% de datos válidos
  lang = "pt",
  verbose = TRUE
)

# Comparar temperatura diaria vs media móvil
df_compare <- df_exact %>%
    dplyr::select(date, tair_dry_bulb_c) %>%
    dplyr::left_join(
      df_moving %>% dplyr::select(date, tair_dry_bulb_c_mean_w14),
      by = "date", relationship = "many-to-many"
    ) %>%
    tidyr::pivot_longer(-date, names_to = "metric", values_to = "temperature")
  ggplot(df_compare, aes(x = date, y = temperature, color = metric)) +
    geom_line(alpha = 0.7) +
    labs(
      title = "Temperatura Diaria vs. Media Móvil (14 días)",
      x = "Fecha",
      y = "Temperatura (°C)",
      color = "Métrica"
    ) +
    theme_minimal()

4.5 Estrategia Offset Window (Ventana Desplazada)

Objetivo: Aislar el período de incubación (excluyendo días recientes). Aplicación: Dengue, Zika, otras enfermedades con período de incubación.

# ============================================================================
# OFFSET WINDOW: Media entre 14 y 7 días antes (ignora la última semana)
# ============================================================================

df_offset <- sus_climate_aggregate(
  health_data = sf_sim_spatial,
  climate_data = df_inmet,
  climate_var = "tair_dry_bulb_c",
  temporal_strategy = "offset_window",
  offset_days = c(7, 14),           # Ventana [t-14, t-7]
  min_obs = 0.7,
  lang = "pt",
  verbose = TRUE
)

head(df_offset)

Interpretación: Esta variable representa la exposición en el período que excluye la semana inmediatamente anterior a la defunción, útil para aislar efectos de largo plazo de exposiciones agudas.


4.6 Estrategia Degree Days (Grados-Día)

Objetivo: Acumular calor por encima de una temperatura base. Aplicación: Desarrollo de vectores (Aedes aegypti), estrés térmico.

# ============================================================================
# DEGREE DAYS: GDD acumulado en los últimos 21 días (base 20°C)
# ============================================================================

df_gdd <- sus_climate_aggregate(
  health_data = sf_sim_spatial,
  climate_data = df_inmet,
  temporal_strategy = "degree_days",
  window_days = 21,                 # Período de acumulación
  temp_base = 20,                   # Temperatura base (humano)
  gdd_temp_var = "tair_dry_bulb_c",
  min_obs = 0.7,
  lang = "pt",
  verbose = TRUE
)

head(df_gdd)

# Ejemplo con temperatura base para Aedes aegypti (11°C)
df_gdd_aedes <- sus_climate_aggregate(
  health_data = sf_sim_spatial,
  climate_data = df_inmet,
  temporal_strategy = "degree_days",
  window_days = 21,
  temp_base = 11,                   # Base para Aedes aegypti
  gdd_temp_var = "tair_dry_bulb_c",
  lang = "pt",
  verbose = TRUE
)

head(df_gdd_aedes)

Umbrales Térmicos por Especie

Organismo Tbase (temp_base) (°C) GDD para Desarrollo Aplicación
Aedes aegypti 11 100-150 Transmisión del dengue
Anopheles gambiae 18 80-120 Transmisión de la malaria
Triatoma infestans 16 200-300 Enfermedad de Chagas
Humano (estrés) 20 - Morbilidad cardiovascular

4.7 Estrategia Seasonal (Estacional)

Objetivo: Analizar patrones estacionales. Aplicación: Estudios ecológicos, tendencias de largo plazo.

# ============================================================================
# SEASONAL: Medias por estación del año
# ============================================================================

df_seasonal <- sus_climate_aggregate(
  health_data = sf_sim_spatial,
  climate_data = df_inmet,
  temporal_strategy = "seasonal",
  lang = "pt",
  verbose = TRUE
)

head(df_seasonal)

4.8 Estrategia Threshold Exceedance (Excedencia de Umbral)

Objetivo: Contar días con temperaturas extremas. Aplicación: Olas de calor, eventos extremos de precipitación.

# ============================================================================
# THRESHOLD EXCEEDANCE: Días con Tmax > 35°C en los últimos 7 días
# ============================================================================

df_threshold <- sus_climate_aggregate(
  health_data = sf_sim_spatial,
  climate_data = df_inmet,
  climate_var = "tair_max_c",
  temporal_strategy = "threshold_exceedance",
  window_days = 7,
  threshold_value = 35,
  threshold_direction = "above",    # Contar días POR ENCIMA del umbral
  min_obs = 0.7,
  lang = "pt",
  verbose = TRUE
)

head(df_threshold)

4.9 Estrategia Weighted Window (Ventana Ponderada)

Objetivo: Aplicar pesos decrecientes a los días de la ventana. Aplicación: Modelar el decaimiento biológico de la exposición.

# ============================================================================
# WEIGHTED WINDOW: Media ponderada con diferentes funciones de peso
# ============================================================================

# Caso 1: Pesos lineales (automáticos)
df_wlin <- sus_climate_aggregate(
  health_data = sf_sim_spatial,
  climate_data = df_inmet,
  climate_var = "tair_dry_bulb_c",
  temporal_strategy = "weighted_window",
  window_days = 7,
  weights = NULL,                   # Decaimiento lineal automático
  min_obs = 0.7,
  lang = "pt",
  verbose = TRUE
)

head(df_wlin)

# Caso 2: Pesos exponenciales (decaimiento rápido)
lambda <- 0.3
W <- 7
pesos_exp <- exp(-lambda * seq(0, W))
pesos_exp <- pesos_exp / pesos_exp[1]  # Normalizar (pico = 1)

df_wexp <- sus_climate_aggregate(
  health_data = sf_sim_spatial,
  climate_data = df_inmet,
  climate_var = "tair_dry_bulb_c",
  temporal_strategy = "weighted_window",
  window_days = W,
  weights = pesos_exp,
  min_obs = 0.7,
  lang = "pt",
  verbose = TRUE
)

head(df_wexp)

# Caso 3: Pesos gaussianos (pico en el medio de la ventana)
mu <- 3          # Pico en el día t-3
sigma <- 1.5     # Ancho de la ventana
pesos_gaus <- exp(-((seq(0, W) - mu)^2) / (2 * sigma^2))
pesos_gaus <- pesos_gaus / max(pesos_gaus)

df_wgaus <- sus_climate_aggregate(
  health_data = sf_sim_spatial,
  climate_data = df_inmet,
  climate_var = "tair_dry_bulb_c",
  temporal_strategy = "weighted_window",
  window_days = W,
  weights = pesos_gaus,
  min_obs = 0.7,
  lang = "pt",
  verbose = TRUE
)
head(df_wgaus)

🎉 Conclusión

La función sus_climate_aggregate() eleva a climasus4r de un simple paquete de limpieza de datos a una herramienta de inferencia epidemiológica.

Al alinear la nomenclatura con el estándar de la comunidad R (moving_window), proporcionar una herramienta matemática única para períodos de incubación (offset_window), e introducir estrategias avanzadas como threshold_exceedance y weighted_window, este paquete garantiza que sus conclusiones sobre “Cómo el clima afecta la salud en Brasil” sean metodológicamente irrefutables y estén listas para su publicación en revistas de alto impacto.


🌲 ¿Tiene comentarios o sugerencias?

¿Tiene alguna idea de mejora o encontró algún error? Haga clic en el botón de abajo para abrir un nuevo issue en GitHub y compartir sus sugerencias directamente con nosotros.

Abrir issue en GitHub