
Detecção e Visualização de Ondas de Frio
Pipeline INMET →
Preenchimento → Indicadores → Ondas de Frio |
sus_climate_compute_coldwaves() e
sus_climate_plot_coldwaves()
Dr. Max Anjos
17 October, 2026
Source:vignettes/ondas_de_frio.Rmd
ondas_de_frio.RmdIntrodução
Ondas de frio são eventos climáticos extremos frequentemente subestimados na agenda de saúde pública brasileira. Embora o Brasil seja conhecido por seu clima quente, o Sul e o Sudeste do país experimentam episódios periódicos de frio intenso associados à penetração de massas polares atlânticas, causando excesso de mortalidade cardiovascular e respiratória — em especial entre idosos, crianças e trabalhadores ao ar livre (Gasparrini et al., 2015; Huynen et al., 2001). Estudos globais estimam que o risco atribuível ao frio supera o do calor em muitas regiões, inclusive em zonas subtropicais (Gasparrini et al., 2015).
No Rio Grande do Sul, frentes frias polares podem reduzir a temperatura em 10–15 °C em menos de 24 horas durante o inverno austral (junho–agosto). Em Porto Alegre, episódios com temperaturas mínimas abaixo de 5 °C duram frequentemente 5 a 10 dias consecutivos, impondo carga adicional sobre o sistema respiratório e cardiovascular de populações vulneráveis. A ausência de sistemas de vigilância de ondas de frio comparáveis aos de ondas de calor contribui para que esse risco permaneça subdiagnosticado nas análises do SUS.
O climasus4r implementa sete metodologias
internacionalmente reconhecidas para detecção de ondas de frio, seguindo
a mesma estrutura de pipeline já disponível para ondas de calor. Este
tutorial demonstra o pipeline completo desde o download de dados INMET
até a visualização interativa dos resultados, utilizando a estação de
Porto Alegre (A801) como caso de estudo.
Nota sobre reprodutibilidade: Todo o pipeline é
determinístico — dado o mesmo período de dados INMET e os mesmos
parâmetros, os resultados são idênticos entre execuções. Os blocos de
código marcados com eval = FALSE precisam de conexão com a
internet para a etapa de download (INMET) e podem demorar alguns minutos
dependendo do período solicitado.
O que é uma onda de frio?
Assim como as ondas de calor, as ondas de frio são definidas por dois componentes:
- Limiar de temperatura — a temperatura (ou índice de conforto térmico) deve cair abaixo de determinado valor crítico, tipicamente definido como um percentil baixo da distribuição histórica (P10, P5) ou como um desvio negativo fixo em relação à média climatológica. Enquanto as ondas de calor usam a cauda superior (P90), as ondas de frio usam a cauda inferior (P10).
- Duração mínima — a condição extrema deve persistir por pelo menos N dias consecutivos (comumente 3 ou 5 dias), distinguindo eventos sustentados de quedas de temperatura isoladas.
A ausência de uma definição universal reflete a variabilidade regional do clima e dos limiares de tolerância fisiológica. O critério INMET para frio, por exemplo, usa um desvio absoluto de −5 °C sobre a temperatura mínima histórica (Tmin − 5 °C), em vez da temperatura máxima utilizada no critério de ondas de calor.
Por que comparar métodos? Em regiões subtropicais como o Rio Grande do Sul, o método INMET — calibrado para a realidade climática nacional usando temperatura mínima — tende a detectar eventos que percentis genéricos podem não capturar em anos atipicamente frios. O ECF (Excess Cold Factor, análogo ao EHF para frio) é o único método que considera o fator de aclimatação: a mesma temperatura mínima é fisiologicamente mais estressante quando ocorre após um período relativamente quente, pois o organismo não teve tempo de se adaptar ao frio. Comparar os sete métodos é uma boa prática de análise de sensibilidade.
Visão geral do pipeline
1. sus_climate_inmet() → 2. sus_climate_fill_inmet() → 3. sus_climate_compute_indicators() → 4. sus_climate_compute_coldwaves() → 5. sus_climate_plot_coldwaves()
Cada etapa recebe o produto da anterior e adiciona informação. A
função sus_climate_compute_coldwaves() espera dados
horários com colunas padronizadas de temperatura e
índices de conforto térmico — exatamente o que
sus_climate_compute_indicators() produz.
Configuração do ambiente
# Instalar climasus4r (GitHub) se necessário
# install.packages("remotes")
# remotes::install_github("MaxAnjos/climasus4r")
library(climasus4r)
library(dplyr)Dependências opcionais: As funções de visualização
requerem ggplot2, ggsci e plotly.
Para gráficos interativos, instale também htmlwidgets. A
etapa de indicadores climáticos requer slider (janelas
deslizantes) e jsonlite.
install.packages(c("ggplot2", "ggsci", "plotly", "htmlwidgets", "slider", "jsonlite"))Etapa 1 — Aquisição de dados climáticos (INMET)
A rede de estações INMET
O Instituto Nacional de Meteorologia (INMET) opera a maior rede de estações meteorológicas automáticas do Brasil, com cobertura em todos os estados. Os dados são disponibilizados em formato CSV com resolução horária e incluem temperatura do ar (bulbo seco, máxima, mínima), umidade relativa, velocidade e direção do vento, pressão atmosférica e precipitação.
A função sus_climate_inmet() automatiza o download, o
parsing e a padronização desses arquivos para um formato pronto para
análise.
Parâmetros principais
# Estrutura da chamada completa
df_inmet <- sus_climate_inmet(
years = 2020:2023, # Vetor de anos
uf = "", # UF (sigla) para filtrar estações
station_code = NULL, # Código(s) específico(s) de estação (opcional)
use_cache = TRUE, # Reutilizar arquivos já baixados
cache_dir = "~/.climasus4r_cache/climate",
parallel = FALSE, # TRUE habilita download paralelo via furrr/future
workers = NULL, # NULL = detectar automaticamente via parallelly
lang = "pt",
verbose = TRUE
)| Parâmetro | Tipo | Descrição |
|---|---|---|
years |
inteiro ou vetor | Anos a baixar (ex.: 2020:2023) |
uf |
character | Sigla do estado para filtrar estações (ex.: "RS",
"SC") |
station_code |
character | Código(s) específico(s) de estação INMET (ex.:
"A801") |
use_cache |
lógico | Se TRUE, reaproveita arquivos já baixados em
cache_dir
|
parallel |
lógico | Habilita download paralelo via
furrr/future (requer múltiplos núcleos) |
workers |
inteiro ou NULL
|
Número de workers; NULL detecta automaticamente via
parallelly
|
Exemplo: estação de Porto Alegre (RS)
Neste tutorial, utilizamos dados da estação automática de Porto Alegre (código INMET A801), no Rio Grande do Sul — estado com o maior registro histórico de ondas de frio do Brasil. Porto Alegre, com latitude de aproximadamente −30°S, está sujeita à penetração regular de massas polares atlânticas durante o inverno austral, tornando-a um laboratório natural para o estudo de eventos de frio extremo.
# Download de dados horários (2020–2023)
# A primeira execução pode levar alguns minutos; execuções subsequentes usam cache.
df_inmet <- sus_climate_inmet(
years = 2020:2023,
uf = "RS", # Porto Alegre - RS
use_cache = TRUE,
parallel = FALSE, # Use TRUE com workers = NULL em máquinas multicore
lang = "pt",
verbose = TRUE
)
# Inspecionar estrutura
glimpse(df_inmet)A saída é um data.frame com resolução horária e colunas
padronizadas pelo climasus4r:
#> Rows: ~35,064 (4 anos x 365 dias x 24 horas)
#> Columns: ~20
#>
#> $ date <POSIXct> 2020-01-01 00:00:00, 2020-01-01 01:00:00 ...
#> $ station_code <chr> 'A801', 'A801', ...
#> $ station_name <chr> 'PORTO ALEGRE', 'PORTO ALEGRE', ...
#> $ federal_unit <chr> 'RS', 'RS', ...
#> $ region <chr> 'Sul', 'Sul', ...
#> $ latitude <dbl> -30.05, -30.05, ...
#> $ longitude <dbl> -51.17, -51.17, ...
#> $ tair_dry_bulb_c <dbl> 14.2, 13.8, ...
#> $ tair_max_c <dbl> 16.1, 15.4, ...
#> $ tair_min_c <dbl> 12.5, 12.1, ...
#> $ rh_pct <dbl> 78.0, 80.0, ...
#> $ wind_speed_ms <dbl> 2.1, 1.8, ...
#> $ precip_mm <dbl> 0.0, 0.0, ...
Origem dos dados: Os dados brutos são os arquivos
CSV disponibilizados publicamente pelo INMET em
https://portal.inmet.gov.br/dadoshistoricos. O
climasus4r faz o parsing automático de cada arquivo anual,
aplica controle de qualidade e padroniza os nomes de colunas. Nenhuma
interpolação ou modificação de valores é realizada nesta etapa.
Etapa 2 — Preenchimento de lacunas (gap-filling)
O problema das lacunas em séries horárias
Estações automáticas do INMET frequentemente apresentam lacunas
causadas por falhas de transmissão, manutenção de equipamentos ou
eventos climáticos extremos. A presença de valores ausentes
(NA) em colunas de temperatura pode inviabilizar o cálculo
de índices de conforto térmico e comprometer as estimativas
percentílicas utilizadas na detecção de ondas de frio.
A função sus_climate_fill_inmet() implementa um
preenchimento inteligente baseado em modelos de regressão treinados com
covariáveis meteorológicas correlacionadas (temperatura do ar, umidade
relativa, velocidade do vento, hora do dia, sazonalidade). O
preenchimento é realizado variável por variável e respeita um limiar
máximo de lacunas (gap_percentage): se a proporção de
valores ausentes em determinada série superar esse limiar, a estação é
marcada como de baixa qualidade e nenhum preenchimento é aplicado.
Parâmetros principais
df_filled <- sus_climate_fill_inmet(
df = df_inmet,
target_var = "tair_dry_bulb_c", # Variável a preencher
datetime_col = NULL, # Detectado automaticamente
station_col = NULL, # Detectado automaticamente
quality_threshold = 0.4, # Máximo de NAs para aceitar a série (40%)
run_evaluation = FALSE, # Se TRUE: avalia métricas de ajuste
gap_percentage = 0.2, # Intervalo máximo de gap contínuo a preencher (20%)
keep_features = FALSE, # Manter covariáveis auxiliares no output
parallel = TRUE,
workers = NULL, # NULL = detectar automaticamente
verbose = TRUE,
lang = "pt"
)Preenchimento do conjunto completo
Na prática, aplicamos o preenchimento a cada variável de temperatura e umidade relevante antes de calcular os indicadores de conforto térmico:
# Preencher temperatura do ar (bulbo seco)
df_filled <- sus_climate_fill_inmet(
df = df_inmet,
target_var = "tair_dry_bulb_c",
lang = "pt",
verbose = TRUE
)
# Preencher temperatura máxima e mínima
df_filled <- sus_climate_fill_inmet(df_filled, target_var = "tair_max_c", lang = "pt")
df_filled <- sus_climate_fill_inmet(df_filled, target_var = "tair_min_c", lang = "pt")
# Preencher umidade relativa (necessária para UTCI, WBGT, HI)
df_filled <- sus_climate_fill_inmet(df_filled, target_var = "rh_pct", lang = "pt")
# Verificar proporção de NAs remanescentes
df_filled |>
summarise(
n_total = n(),
na_tmax = mean(is.na(tair_max_c)),
na_tmin = mean(is.na(tair_min_c)),
na_tair = mean(is.na(tair_dry_bulb_c)),
na_rh = mean(is.na(rh_pct))
)Boa prática: Sempre aplique
sus_climate_fill_inmet() antes de
sus_climate_compute_coldwaves(). A função de detecção emite
um aviso (cli_warn) se encontrar NAs nas
colunas de temperatura, mas não os preenche
automaticamente — essa decisão cabe ao analista, pois diferentes
estratégias de imputação podem influenciar os resultados.
Etapa 3 — Cálculo de indicadores climáticos
Por que ir além da temperatura do ar?
A temperatura do ar (bulbo seco) é a variável meteorológica mais disponível, mas não é a melhor proxy para o estresse térmico humano em condições de frio. O corpo humano responde ao ambiente frio resultante da combinação de temperatura, umidade, velocidade do vento (fator de resfriamento eólico) e radiação. Índices de conforto térmico integram esses fatores e permitem estimar a percepção fisiológica do frio de forma mais realista.
A função sus_climate_compute_indicators() calcula os
principais índices utilizados nas metodologias de detecção de ondas de
frio implementadas no climasus4r. Para ondas de frio, o
interesse recai sobre os valores mínimos diários desses
índices:
<div class="feature-icon">🌬️</div>
<h3>UTCI</h3>
<p><strong>Universal Thermal Climate Index.</strong> Modelo biometeorológico de referência da ISO 15743. Integra temperatura, umidade, vento e radiação em uma temperatura equivalente fisiológica (°C). Em frio extremo, UTCI abaixo de −13 °C indica estresse frio forte.</p>
<div class="feature-icon">❄️</div>
<h3>WBGT</h3>
<p><strong>Wet Bulb Globe Temperature.</strong> Índice operacional amplamente utilizado em saúde ocupacional. Em regimes frios, valores baixos de WBGT indicam risco de hipotermia e lesões por congelamento em trabalhadores ao ar livre.</p>
<div class="feature-icon">🧊</div>
<h3>HI</h3>
<p><strong>Heat Index (Índice de Calor).</strong> Embora concebido para calor, valores baixos do HI mínimo diário podem ser usados como indicador de conforto térmico precário em condições de frio e alta umidade.</p>
<div class="feature-icon">🌿</div>
<h3>PET</h3>
<p><strong>Physiological Equivalent Temperature.</strong> Temperatura de um ambiente de referência com as mesmas trocas de calor do corpo. Em valores negativos, indica desconforto fisiológico intenso por frio.</p>
Chamada da função
df_indicators <- sus_climate_compute_indicators(
df = df_filled,
indicators = "all", # Calcular todos os indicadores disponíveis
region = "auto", # Detectar região automaticamente por metadados
apply_validity_mask = TRUE, # Mascarar valores fora dos limites físicos
verify_physics = TRUE, # Verificar consistência física (Tmin <= Tmean <= Tmax)
keep_source_vars = TRUE, # Manter variáveis originais no output
verbose = TRUE,
lang = "pt"
)
# Verificar colunas adicionadas
names(df_indicators) |> grep("utci|wbgt|hi_c|pet", x = _, value = TRUE)Após esta etapa, o data.frame contém as colunas
adicionais necessárias para a detecção de ondas de frio pelos métodos
UTCI, WBGT e HI:
| Coluna nova | Índice | Unidade |
|---|---|---|
utci_c |
UTCI | °C |
wbgt_c |
WBGT | °C |
hi_c |
Heat Index | °C |
pet_c |
PET | °C |
utci_c_flag_extreme |
Horas com UTCI > 38 °C | lógico |
wbgt_c_flag_extreme |
Horas com WBGT > 32 °C | lógico |
hi_c_flag_extreme |
Horas com HI > 51 °C | lógico |
Faixas frias do UTCI: A norma ISO 15743 define
categorias de estresse frio pelo UTCI: sem estresse térmico (≥ 9 °C),
leve estresse frio (0–9 °C), estresse frio moderado (−13 a 0 °C), forte
estresse frio (−27 a −13 °C) e estresse frio muito forte (< −27 °C).
Na detecção de ondas de frio, o método UTCI no climasus4r
utiliza o UTCImin diário — o menor valor horário de
UTCI registrado naquele dia — comparado com o P10 histórico desse mesmo
indicador.
Etapa 4 — Detecção de ondas de frio
A função sus_climate_compute_coldwaves()
Esta é a função central do módulo de detecção de frio do
climasus4r. Ela recebe dados horários (produto de
sus_climate_compute_indicators()), os agrega para escala
diária, calcula limiares históricos percentílicos por estação do ano
(usando uma janela deslizante de ±15 dias ao redor de cada dia do ano),
aplica cada metodologia de detecção selecionada e retorna uma lista
estruturada com três componentes.
Assinatura completa
cw_result <- sus_climate_compute_coldwaves(
df = df_indicators, # Output de sus_climate_compute_indicators()
method = c("WHO", "WMO", "INMET", "EHF", "UTCI", "WBGT", "HI"),
baseline_start = "2020-01-01", # Início do período de referência
baseline_end = "2022-12-31", # Fim do período de referência
percentile = 10, # Percentil para limiares (P10 para cauda fria)
min_duration = NULL, # NULL = usar defaults por método
lang = "pt",
verbose = TRUE
)Nota sobre o argumento method = "EHF":
O identificador "EHF" é mantido por consistência com a API
de ondas de calor, mas internamente a função aplica o algoritmo do
Excess Cold Factor (ECF) — o análogo frio do EHF. O ECF
foi proposto por Nairn & Fawcett (2015) e adaptado aqui para
detectar eventos de frio extremo com base em temperatura média diária e
fator de aclimatação.
Metodologias implementadas
A Tabela 1 apresenta as sete metodologias implementadas, incluindo a variável-base, o critério de limiar e a duração mínima padrão.
Tabela 1 — Metodologias de detecção de ondas de frio
implementadas em
sus_climate_compute_coldwaves()
| Método | Variável-base | Critério de limiar | Duração mínima | Referência |
|---|---|---|---|---|
| WHO | Tmin diária | Tmin < P10(Tmin) | 3 dias | WMO & WHO (2015) |
| WMO | Tmin e Tmax diárias | Tmin < P10(Tmin) E Tmax < P10(Tmax) | 5 dias | Perkins & Alexander (2013) |
| INMET | Tmin diária | Tmin < média histórica − 5 °C | 5 dias | INMET (2009) |
| ECF | Tmean diária | ECF > 0 (fórmula composta; ver abaixo) | 3 dias | Nairn & Fawcett (2015)* |
| UTCI | UTCImin diário | UTCImin < P10(UTCImin) | 3 dias | ISO 15743 |
| WBGT | WBGTmin diário | WBGTmin < P10(WBGTmin) | 3 dias | Liljegren et al. (2008) |
| HI | HImin diário | HImin < P10(HImin) | 3 dias | Steadman (1979) |
*Adaptação para frio: ECF (Excess Cold Factor) em vez de EHF (Excess Heat Factor).
Suavização sazonal dos percentis: Para todos os
métodos baseados em percentil, o climasus4r utiliza uma
janela deslizante de ±15 dias em torno de cada dia do ano (calculada
sobre o período de referência), e não um percentil fixo calculado sobre
toda a série. Essa abordagem, recomendada por Fischer & Schär
(2010), elimina o viés sazonal e garante que o mesmo nível de
extremidade relativa seja detectado em qualquer época do ano. Para ondas
de frio, o percentil é calculado na cauda inferior da
distribuição (P10), em oposição ao P90 usado para ondas de calor.
Fundamentos do Excess Cold Factor (ECF)
O ECF é o análogo frio do EHF (Nairn & Fawcett, 2015). Ele combina dois componentes que capturam, respectivamente, a magnitude absoluta do frio e o fator de aclimatação da população:
Onde:
- ECI_sig (índice de significância do frio): , mede o quanto a temperatura média dos últimos 3 dias está abaixo do percentil 5 climatológico da temperatura média. Valores positivos indicam frio fisiologicamente relevante.
- ECI_acc (índice de aclimatação): , mede o quanto a temperatura média dos últimos 3 dias está abaixo da média dos 30 dias anteriores. Positivo quando o período recente é mais frio que o mês anterior — ou seja, o organismo estava aclimatado ao calor e foi subitamente exposto ao frio, amplificando o estresse fisiológico.
O multiplicador garante que eventos de frio que ocorrem após período relativamente quente recebam maior peso — exatamente o inverso da lógica do EHF, onde o aquecimento súbito amplifica o risco de calor.
Dias com ECF > 0 são classificados como dias de onda de frio. A intensidade do evento é classificada em três categorias com base no percentil 85 (ECF85) de todos os valores positivos de ECF observados na estação:
- Baixa Intensidade (LICW): 0 < ECF_peak < ECF85
- Severa (SCW): ECF85 ≤ ECF_peak < 3 × ECF85
- Extrema (ECW): ECF_peak ≥ 3 × ECF85
Método INMET: calibração para o frio no Brasil
O método INMET para frio define onda de frio quando a temperatura mínima diária cai abaixo da média climatológica da temperatura mínima por pelo menos 5 °C por 5 ou mais dias consecutivos (INMET, 2009). Diferentemente do critério de ondas de calor (que usa a temperatura máxima), o critério de frio usa a temperatura mínima — a variável mais sensível à penetração de massas polares.
A média climatológica da Tmin é calculada sobre o período de referência definido pelo usuário, utilizando a mesma janela deslizante de ±15 dias usada nos percentis. Esse critério é particularmente adequado para o Sul do Brasil, onde os valores absolutos de Tmin já são baixos e a vulnerabilidade à mortalidade por frio está mais associada ao desvio em relação à norma local do que ao valor absoluto.
Executando a detecção
Exemplo 1: métodos baseados em temperatura do ar
# Métodos que requerem apenas temperatura do ar (Tmax, Tmin, Tmean)
cw_temp <- sus_climate_compute_coldwaves(
df = df_indicators,
method = c("WHO", "WMO", "INMET", "EHF"),
baseline_start = "2020-01-01",
baseline_end = "2022-12-31",
percentile = 10,
lang = "pt",
verbose = TRUE
)Exemplo 2: todos os métodos (incluindo índices de conforto)
# Todos os métodos — requer colunas utci_c, wbgt_c, hi_c
cw_all <- sus_climate_compute_coldwaves(
df = df_indicators,
method = "all", # Equivale a c("WHO","WMO","INMET","EHF","UTCI","WBGT","HI")
baseline_start = "2020-01-01",
baseline_end = "2022-12-31",
percentile = 10,
lang = "pt",
verbose = TRUE
)Exemplo 3: critério conservador
# Critério mais conservador: P5 e mínimo de 5 dias para todos os métodos
cw_strict <- sus_climate_compute_coldwaves(
df = df_indicators,
method = c("WHO", "INMET"),
baseline_start = "2020-01-01",
baseline_end = "2022-12-31",
percentile = 5, # Limiar mais restritivo → menos eventos, mais intensos
min_duration = 5, # Substitui os defaults por método
lang = "pt",
verbose = TRUE
)Análise de sensibilidade: Recomenda-se executar a detecção com diferentes combinações de percentil (P5, P10, P15) e duração mínima (3, 5, 7 dias) e comparar o número de eventos detectados. Isso permite avaliar a robustez dos resultados epidemiológicos em relação às escolhas metodológicas.
Baseline curto neste tutorial: Este tutorial usa
apenas 4 anos de dados (2020–2023) para agilizar o download. O
climasus4r emite um aviso quando o baseline tem menos de 20
anos, o que é esperado aqui. Para pesquisa real, recomenda-se usar pelo
menos 1981–2010 ou 1991–2020 como período de referência
climatológica.
Estrutura do output
A função retorna uma lista nomeada com três componentes — mesma
estrutura do output de sus_climate_compute_heatwaves(), mas
com nomenclatura adaptada para frio:
# Inspecionar o output
names(cw_all)
#> [1] "events" "daily" "summary"
$events — tabela de eventos
Um data.frame com uma linha por evento de onda de frio
detectado. Cada linha representa um episódio contínuo de dias com a
condição de onda de frio ativa para um determinado método e estação.
# Primeiros eventos detectados
head(cw_all$events)| Coluna | Tipo | Descrição |
|---|---|---|
event_id |
character | Identificador único:
<estação>_<método>_<N>
|
station_code |
character | Código INMET da estação |
method |
character | Método de detecção (WHO, WMO, etc.) |
start_date |
Date | Data de início do evento |
end_date |
Date | Data de fim do evento |
duration_days |
integer | Duração em dias consecutivos |
temp_mean |
double | Temperatura média do período (variável do método) |
temp_peak |
double | Temperatura mais fria do período (mínimo) |
anomaly_mean |
double | Anomalia média (limiar − temperatura; positivo = mais frio que o limiar) |
anomaly_cumulative |
double | Anomalia acumulada ao longo do evento |
severity_index |
double | Índice de severidade: duração × anomalia média |
ecf_peak |
double | Pico do ECF (apenas método EHF/ECF; NA para outros) |
ecf_mean |
double | Média do ECF durante o evento (apenas EHF/ECF) |
intensity_class |
character | Classificação: LICW, SCW, ECW (apenas EHF/ECF) |
region |
character | Região geográfica da estação |
federal_unit |
character | UF da estação |
Diferenças importantes em relação ao output de ondas de calor:
| Campo | Ondas de Calor | Ondas de Frio |
|---|---|---|
temp_peak |
Temperatura mais quente do evento | Temperatura mais fria do evento |
anomaly_mean |
temp − limiar (positivo = mais quente) |
limiar − temp (positivo = mais frio) |
| Flags diários |
hw_who, hw_any, … |
cw_who, cw_any, … |
| ECF-específico |
ehf_peak, ehf_mean
|
ecf_peak, ecf_mean
|
| Resumo anual | total_days_hw |
total_days_cw |
| Classes de intensidade | LIHW, SHW, EHW | LICW, SCW, ECW |
# Filtrar os 10 eventos mais severos pelo índice de severidade
cw_all$events |>
arrange(desc(severity_index)) |>
select(event_id, method, start_date, end_date, duration_days,
temp_peak, anomaly_mean, severity_index) |>
head(10)
# Contar eventos por método
cw_all$events |>
count(method, name = "n_eventos") |>
arrange(desc(n_eventos))
$daily — série diária com flags
O data.frame diário contém uma linha por estação por
dia, com as variáveis agregadas e colunas lógicas
(TRUE/FALSE) indicando se aquele dia pertence
a uma onda de frio segundo cada método:
# Inspecionar colunas de flags
cw_all$daily |>
select(station_code, date_day, tmin, tmean, starts_with("cw_")) |>
head(10)A coluna cw_any é TRUE se
qualquer método detectou onda de frio naquele dia —
útil para análises de exposição sem comprometimento com um único
critério.
# Dias com onda de frio ativa por pelo menos um método
cw_all$daily |>
filter(cw_any == TRUE) |>
select(date_day, tmin, tmean, cw_who, cw_inmet, cw_ehf, cw_utci) |>
head(20)
# Concordância entre métodos: proporção de dias classificados por cada um
cw_all$daily |>
summarise(
pct_who = mean(cw_who, na.rm = TRUE) * 100,
pct_wmo = mean(cw_wmo, na.rm = TRUE) * 100,
pct_inmet = mean(cw_inmet, na.rm = TRUE) * 100,
pct_ehf = mean(cw_ehf, na.rm = TRUE) * 100,
pct_utci = mean(cw_utci, na.rm = TRUE) * 100,
pct_wbgt = mean(cw_wbgt, na.rm = TRUE) * 100,
pct_hi = mean(cw_hi, na.rm = TRUE) * 100,
pct_any = mean(cw_any, na.rm = TRUE) * 100
)
$summary — resumo anual
O resumo anual agrega as estatísticas por estação, método e ano, sendo o ponto de entrada natural para análises de tendência temporal:
# Resumo anual
cw_all$summary |>
filter(method == "INMET") |>
select(year, station_code, n_events, total_days_cw,
mean_duration, max_duration, mean_anomaly, severity_total) |>
arrange(desc(year))| Coluna | Descrição |
|---|---|
year |
Ano |
station_code |
Código da estação |
method |
Método de detecção |
n_events |
Número de eventos no ano |
total_days_cw |
Total de dias de onda de frio no ano |
mean_duration |
Duração média dos eventos (dias) |
max_duration |
Duração do evento mais longo (dias) |
mean_intensity |
Temperatura média nos eventos |
max_intensity |
Temperatura de pico (mais fria) nos eventos |
mean_anomaly |
Anomalia média nos eventos |
severity_total |
Soma dos índices de severidade dos eventos no ano |
Etapa 5 — Visualização de ondas de frio
A função sus_climate_plot_coldwaves()
A visualização transforma o output estruturado de
sus_climate_compute_coldwaves() em gráficos interpretativos
com paleta de cores frias (tons de azul e violeta). A função oferece
quatro tipos de visualização, cada um respondendo a uma pergunta
analítica diferente:
<div class="feature-icon">📅</div>
<h3>timeline</h3>
<p>Diagrama de Gantt mostrando a posição temporal, duração e intensidade de cada evento. Ideal para identificar episódios de frio prolongados no inverno austral e comparar métodos.</p>
<div class="feature-icon">🗓️</div>
<h3>calendar</h3>
<p>Mapa de calor calendário que exibe a ocorrência diária de ondas de frio ao longo dos meses. Revela a concentração sazonal (inverno austral) e padrões interanuais associados a La Niña.</p>
<div class="feature-icon">❄️</div>
<h3>intensity</h3>
<p>Dispersão duração × temperatura mínima de pico, com eixo Y invertido (mais frio = mais alto). Distingue eventos longos de eventos com temperaturas extremamente baixas.</p>
<div class="feature-icon">📈</div>
<h3>trend</h3>
<p>Barras agrupadas do número de eventos por ano e método. Permite identificar variabilidade interanual e possíveis tendências na frequência de ondas de frio.</p>
Assinatura completa
p <- sus_climate_plot_coldwaves(
cw_result = cw_all, # Output de sus_climate_compute_coldwaves()
type = "timeline", # "timeline" | "calendar" | "intensity" | "trend"
station_code = NULL, # Filtrar por estação específica
method = NULL, # Filtrar por método (ex.: "INMET", "EHF")
year = NULL, # Filtrar por ano (útil para "calendar")
interactive = TRUE, # TRUE = plotly; FALSE = ggplot2 estático
color_palette = "npg", # Paleta ggsci: "npg", "lancet", "jama", etc.
lang = "pt", # "pt" | "en" | "es"
save_plot = NULL # Caminho para salvar (HTML ou PNG)
)| Parâmetro | Opções | Efeito |
|---|---|---|
type |
"timeline", "calendar",
"intensity", "trend"
|
Tipo de gráfico |
interactive |
TRUE (plotly), FALSE (ggplot2) |
Interatividade |
color_palette |
qualquer paleta do pacote ggsci
|
Esquema de cores (aplicado sobre paleta base de azuis) |
lang |
"pt", "en", "es"
|
Idioma dos rótulos |
save_plot |
caminho .html ou .png
|
Salvar o gráfico em disco |
Plot 1: Linha do tempo (timeline)
O gráfico de linha do tempo apresenta cada evento como um segmento horizontal (estilo Gantt), com espessura proporcional à duração e cor indicando a classe de intensidade ECF (para o método EHF/ECF; para outros métodos, eventos são exibidos em azul uniforme).
# Linha do tempo de todos os eventos — todos os métodos
sus_climate_plot_coldwaves(
cw_result = cw_all,
type = "timeline",
interactive = TRUE,
lang = "pt"
)
# Filtrar apenas eventos pelo método INMET
sus_climate_plot_coldwaves(
cw_result = cw_all,
type = "timeline",
method = "INMET",
interactive = TRUE,
lang = "pt"
)
# Versão estática para publicação
p_timeline <- sus_climate_plot_coldwaves(
cw_result = cw_all,
type = "timeline",
method = c("WHO", "INMET", "EHF"),
interactive = FALSE, # ggplot2 puro
color_palette = "lancet", # Paleta Lancet (jornais biomédicos)
lang = "pt",
save_plot = "timeline_ondas_frio.png" # Salvar em PNG
)
print(p_timeline)Interpretação: Segmentos mais longos indicam eventos mais duradouros; a espessura reforça visualmente a duração. Observe a concentração de eventos em junho–agosto (inverno austral). O método WMO (duplo limiar: Tmin e Tmax < P10) tende a gerar menos eventos e de maior duração que o WHO (apenas Tmin), pois exige que tanto o dia quanto a noite sejam excepcionalmente frios.
Plot 2: Calendário (calendar)
O calendário exibe cada dia do ano em células coloridas — azul para dias de onda de frio, cinza para dias normais. É o gráfico mais intuitivo para comunicar a sazonalidade dos eventos ao público não técnico.
# Calendário para um ano específico — método WHO
sus_climate_plot_coldwaves(
cw_result = cw_all,
type = "calendar",
method = "WHO",
year = 2021,
interactive = TRUE,
lang = "pt"
)
# Calendário com cw_any (qualquer método) — todos os anos
sus_climate_plot_coldwaves(
cw_result = cw_all,
type = "calendar",
method = NULL, # NULL → usa cw_any (qualquer método)
interactive = FALSE,
lang = "pt"
)Interpretação: Observe a concentração de dias de onda de frio em junho, julho e agosto no Sul do Brasil. Anos com eventos La Niña (que tendem a intensificar frentes frias no RS) apresentam calendários com mais blocos azuis consecutivos. Esses períodos merecem atenção especial na análise de mortalidade respiratória e cardiovascular no SUS.
Plot 3: Intensidade vs. duração (intensity)
Este gráfico de dispersão posiciona cada evento no plano cartesiano
duração × temperatura mínima de pico. O eixo Y é
invertido (scale_y_reverse()), de modo que
temperaturas mais baixas (mais frias, mais extremas) aparecem na parte
superior do gráfico — convenção que torna intuitiva a interpretação:
quanto mais alto e à direita, maior o risco epidemiológico.
# Intensidade ECF (com classificação LICW / SCW / ECW)
sus_climate_plot_coldwaves(
cw_result = cw_all,
type = "intensity",
method = "EHF", # "EHF" aciona o algoritmo ECF
interactive = TRUE,
lang = "pt"
)
# Todos os métodos juntos (sem classificação de intensidade ECF)
sus_climate_plot_coldwaves(
cw_result = cw_all,
type = "intensity",
method = NULL,
interactive = FALSE,
lang = "pt"
)Interpretação: Eventos no quadrante superior direito (longa duração + temperatura muito baixa) são os mais perigosos do ponto de vista de saúde pública. O ECF captura a nuance de aclimatação: um evento com Tmin de 5 °C após um período de inverno consolidado é menos estressante do que a mesma temperatura ocorrendo imediatamente após dias quentes — exatamente o que o componente ECI_acc mede.
Plot 4: Tendência anual (trend)
O gráfico de tendência mostra o número de eventos detectados por ano para cada método, permitindo avaliar a variabilidade interanual e possíveis tendências na frequência de ondas de frio ao longo do período analisado.
# Tendência anual — todos os métodos
sus_climate_plot_coldwaves(
cw_result = cw_all,
type = "trend",
interactive = TRUE,
lang = "pt"
)
# Tendência apenas para WHO e INMET (comparação de sensibilidade)
sus_climate_plot_coldwaves(
cw_result = cw_all,
type = "trend",
method = c("WHO", "INMET"),
interactive = FALSE,
lang = "pt",
save_plot = "tendencia_ondas_frio.png"
)Interpretação: A variabilidade interanual de ondas de frio é grande e fortemente influenciada pelo ENSO (El Niño–Oscilação Sul): La Niña tende a aumentar a frequência e intensidade de frentes frias no Sul do Brasil. Compare os padrões entre métodos: o método INMET tende a ser mais restritivo (exige desvio de −5 °C sobre a Tmin histórica), enquanto os métodos percentílicos capturam a relatividade do evento em relação ao histórico local.
Salvando gráficos
# Gráfico interativo → arquivo HTML autossuficiente
sus_climate_plot_coldwaves(
cw_result = cw_all,
type = "timeline",
interactive = TRUE,
lang = "pt",
save_plot = "ondas_frio_timeline.html"
)
# Gráfico estático → PNG de alta resolução (300 dpi)
sus_climate_plot_coldwaves(
cw_result = cw_all,
type = "trend",
interactive = FALSE,
lang = "pt",
save_plot = "ondas_frio_tendencia.png" # ggsave com dpi=300
)Análise avançada dos resultados
Integrando eventos ao calendário epidemiológico
O componente $daily com a coluna cw_any
pode ser diretamente cruzado com dados de mortalidade e morbidade do SUS
para calcular excesso de óbitos e internações durante ondas de frio:
# Exemplo conceitual: cruzamento com dados de mortalidade SIM
# (após completar o pipeline de importação dos dados SIM)
# 1. Preparar a série diária de mortalidade respiratória em idosos
# df_sim_diario <- sus_data_aggregate(df_sim, by = "day") |>
# filter(
# cid_grupo %in% c("J"), # Doenças respiratórias (CIDs J00-J99)
# idade >= 65 # Idosos - grupo mais vulnerável ao frio
# )
# 2. Adicionar flag de onda de frio
# df_analise <- df_sim_diario |>
# left_join(
# cw_all$daily |> select(date_day, cw_any, cw_inmet, tmin),
# by = c("date" = "date_day")
# )
# 3. Comparar mortalidade em dias com/sem onda de frio
# df_analise |>
# group_by(cw_any) |>
# summarise(
# n_dias = n(),
# obitos_medio = mean(n_obitos, na.rm = TRUE),
# sd = sd(n_obitos, na.rm = TRUE)
# )Análise de concordância entre métodos
# Proporção de dias classificados como onda de frio por N métodos simultaneamente
cw_all$daily |>
mutate(
n_methods = rowSums(
across(c(cw_who, cw_wmo, cw_inmet, cw_ehf, cw_utci, cw_wbgt, cw_hi)),
na.rm = TRUE
)
) |>
count(n_methods) |>
mutate(pct = round(n / sum(n) * 100, 1))A análise de concordância responde a uma pergunta central da epidemiologia ambiental: em quantos dos dias classificados como onda de frio há consenso entre os métodos? Alta concordância aumenta a confiança nos resultados; baixa concordância sugere que o impacto em saúde pode variar significativamente dependendo do critério adotado.
Referências
Mortalidade por frio — epidemiologia global
- Gasparrini, A., Guo, Y., Hashizume, M., Lavigne, E., Zanobetti, A., Schwartz, J., … & Armstrong, B. (2015). Mortality risk attributable to high and low ambient temperature: a multicountry observational study. The Lancet, 386(9991), 369–375. https://doi.org/10.1016/S0140-6736(14)62114-0
- Huynen, M.M.T.E., Martens, P., Schram, D., Weijenberg, M.P. & Kunst, A.E. (2001). The impact of heat waves and cold spells on mortality rates in the Dutch population. Environmental Health Perspectives, 109(5), 463–470.
- Basu, R. & Samet, J.M. (2002). Relation between elevated ambient temperature and mortality: a review of the epidemiologic evidence. Epidemiologic Reviews, 24(2), 190–202.
Contexto Brasil e Sul
- Braga, A.L.F., Zanobetti, A. & Schwartz, J. (2001). The time course of weather-related deaths. Epidemiology, 12(6), 662–667.
- Vasconcelos, J., Freire, E., Morais, J., Machado, J.R. & Santana, P. (2013). The health impacts of poor housing conditions and thermal discomfort. Procedia Environmental Sciences, 19, 107–112.
Conceitos gerais e framework de percentis
- Perkins, S.E. & Alexander, L.V. (2013). On the measurement of heat waves. Journal of Climate, 26(13), 4500–4517.
- Fischer, E.M. & Schär, C. (2010). Consistent geographical patterns of changes in high-impact European heatwaves. Nature Geoscience, 3, 398–403.
Métodos WHO e WMO (adaptados para frio)
- WMO & WHO (2015). Heatwaves and Health: Guidance on Warning-System Development. Organização Meteorológica Mundial, Genebra.
- WMO (2021). Guidelines on the Definition and Monitoring of Extreme Weather and Climate Events. Organização Meteorológica Mundial.
Método INMET
- INMET — Instituto Nacional de Meteorologia (2009). Normais Climatológicas do Brasil 1961–1990. Brasília: MAPA/INMET.
ECF (Excess Cold Factor)
- Nairn, J.R. & Fawcett, R.J.B. (2015). The Excess Heat Factor: A metric for heatwave intensity and its use in classifying heatwave severity. International Journal of Environmental Research and Public Health, 12(1), 227–253. https://doi.org/10.3390/ijerph120100227
UTCI (Universal Thermal Climate Index) — regime frio
- Broede, P., Fiala, D., Blazejczyk, K., Holmer, I., Jendritzky, G., Kampmann, B., Tinz, B. & Havenith, G. (2012). Deriving the operational procedure for the Universal Thermal Climate Index (UTCI). International Journal of Biometeorology, 56(3), 481–494. https://doi.org/10.1007/s00484-011-0454-1
- ISO 15743:2008. Ergonomics of the thermal environment — Cold workplaces: Risk assessment and management. Organização Internacional de Normalização.
WBGT (Wet Bulb Globe Temperature)
- Liljegren, J.C., Carhart, R.A., Lawday, P., Tschopp, S. & Sharp, R. (2008). Modeling the wet bulb globe temperature using standard meteorological measurements. Journal of Occupational and Environmental Hygiene, 5(10), 645–655.
HI (Heat Index)
- Steadman, R.G. (1979). The assessment of sultriness. Part I: A temperature-humidity index based on human physiology and clothing science. Journal of Applied Meteorology, 18(7), 861–873.
- Steadman, R.G. (1984). A universal scale of apparent temperature. Journal of Applied Meteorology and Climatology, 23(12), 1674–1687.