Casos de dengue em Recife – 2025

Introdução

As arboviroses representam um dos principais desafios de saúde pública no Brasil, especialmente em regiões urbanas densamente povoadas e com condições ambientais favoráveis à proliferação do mosquito Aedes aegypti. Entre as doenças de maior impacto estão a dengue, zika e chikungunya, responsáveis por milhares de notificações anuais, internações hospitalares e impactos sociais e econômicos significativos.

A cidade do Recife apresenta histórico recorrente de surtos dessas doenças devido a fatores como clima tropical, alta densidade populacional e desigualdades urbanas que podem favorecer a formação de criadouros do vetor transmissor. Nesse contexto, compreender os padrões dessas notificações torna-se fundamental para apoiar ações de vigilância, prevenção e controle.

O problema abordado neste trabalho consiste em analisar dados do portal de dados abertos da Prefeitura do Recife contendo notificações de dengue com o objetivo de identificar padrões temporais, espaciais, clínicos e demográficos presentes nos casos registrados ao longo de 2025. Embora os dados estejam disponíveis publicamente, sua estrutura bruta dificulta a extração imediata de informações relevantes, tornando necessária a realização de etapas de preparação, integração e exploração analítica dos dados. Além da base principal, também foram utilizadas tabelas auxiliares contendo descrições dos agravos e códigos de municípios, permitindo enriquecer e contextualizar as análises realizadas.

A análise é relevante porque permite compreender:

  • quais regiões apresentam maior concentração de casos;
  • quais grupos populacionais são mais afetados;
  • como os casos evoluem clinicamente;
  • e como as notificações se distribuem ao longo do tempo.

A metodologia adotada envolveu:

  • importação e limpeza dos dados;
  • tratamento de valores ausentes;
  • padronização de variáveis;
  • integração entre diferentes tabelas;
  • criação de novas variáveis;
  • análise exploratória;
  • e construção de visualizações gráficas e tabelas interativas.

Pacotes necessários

Os pacotes apresentados a seguir são necessários para a execução deste projeto. Eles foram utilizados para importação, limpeza, manipulação, visualização e exploração interativa dos dados analisados.

Pacote Utilização
library(tidyverse) utilizado para manipulação, transformação e visualização de dados
library(lubridate) utilizado para conversão e manipulação de datas
library(janitor) utilizado para padronização e limpeza dos nomes das colunas
library(plotly) utilizado para criação de gráficos interativos
library(DT) utilizado para construção de tabelas interativas
library(scales) utilizado para formatação de escalas e percentuais em gráficos
library(tidyverse)
library(lubridate)
library(janitor)
library(plotly)
library(DT)
library(scales)

Preparação dos dados

Os dados utilizados neste trabalho foram obtidos no portal de dados abertos da Prefeitura do Recife, através do conjunto Casos de Dengue 2025. O objetivo original da base é registrar notificações epidemiológicas relacionadas às arboviroses monitoradas pelo sistema de vigilância em saúde pública.

O conjunto principal contém notificações individuais registradas ao longo de 2025, incluindo informações demográficas, clínicas, laboratoriais e geográficas dos pacientes. Além da tabela principal, foram utilizadas tabelas auxiliares contendo descrições dos agravos e códigos dos municípios brasileiros.

A base original possuía 131 variáveis e 9.187 registros.

Importação dos dados

# base principal
dados <- read.csv('dengue2025.csv', fileEncoding = 'UTF-8', stringsAsFactors = FALSE)
dim(dados)
## [1] 9187  131
# tabela de agravos
agravos <- read.csv('tabelaAgravos.csv', fileEncoding = 'UTF-8', stringsAsFactors = FALSE)

# tabela de municípios
municipios <- read.csv('tabelaMunicipios.csv', fileEncoding = 'UTF-8', stringsAsFactors = FALSE)

Agora padronizando os nomes das colunas:

names(agravos)
## [1] "X_id"        "CÃ.digo.CID" "Agravo"
names(municipios)
## [1] "X_id"      "UF"        "Código"    "Município"
names(agravos)[1:3] <- c(
  "x_id",
  "id_agravo",
  "descricao_agravo"
)

names(municipios)[1:4] <- c(
  "x_id",
  "uf",
  "id_municip",
  "municipio"
)

dados <- clean_names(dados)
agravos <- clean_names(agravos)
municipios <- clean_names(municipios)

Limpeza e transformação

Nesta etapa foram realizadas transformações para padronizar os dados e facilitar as análises.

Primeiramente, convertendo o formato das datas de notificação e das datas de nascimento:

str(dados$dt_notific)
##  chr [1:9187] "2025-04-03T00:00:00" "2025-04-03T00:00:00" ...
str(dados$dt_nasc)
##  chr [1:9187] "1982-09-01T00:00:00" "2007-05-12T00:00:00" ...
# conversão de datas
dados <- dados %>%
  mutate(
    dt_notific = ymd_hms(dt_notific),
    dt_nasc = ymd_hms(dt_nasc)
  )

str(dados$dt_notific)
##  POSIXct[1:9187], format: "2025-04-03" "2025-04-03" "2025-08-03" "2025-03-27" "2025-02-03" ...
str(dados$dt_nasc)
##  POSIXct[1:9187], format: "1982-09-01" "2007-05-12" "1963-08-19" "2021-08-21" "2002-02-18" ...

Agora criando uma variável de idade a partir da data de nascimento e da data da notificação:

# criando idade aproximada
dados <- dados %>%
  mutate(
    idade = year(dt_notific) - year(dt_nasc)
  )

str(dados$idade)
##  num [1:9187] 43 18 62 4 23 58 52 30 40 40 ...

Padronização da coluna de sexo:

unique(dados$cs_sexo)
## [1] "M" "F" "I" ""
dados <- dados %>%
  mutate(
    sexo = case_when(
      cs_sexo == "M" ~ "Masculino",
      cs_sexo == "F" ~ "Feminino",
      TRUE ~ "Ignorado"
    )
  )

Criando uma coluna com uma descrição da evolução dos casos:

dados <- dados %>%
  mutate(
    evolucao_desc = case_when(
      evolucao == 1 ~ "Cura",
      evolucao == 2 ~ "Óbito pelo agravo",
      evolucao == 3 ~ "Óbito por outras causas",
      TRUE ~ "Ignorado"
    )
  )

E por fim removendo as colunas muito vazias:

porcentagem_na <- sapply(dados, function(x) mean(is.na(x)))

dados_limpos <- dados %>%
  select(which(porcentagem_na < 0.8))

dim(dados_limpos)
## [1] 9187   63

Integrando tabelas

Para tornar os dados mais interpretáveis, os códigos de agravos e municípios foram associados às suas respectivas descrições textuais por meio de operações de junção (join).

# merge com agravos
dados_limpos <- dados_limpos %>%
  left_join(
    agravos %>% select(id_agravo, descricao_agravo),
    by = "id_agravo"
  )

# merge com municípios
dados_limpos <- dados_limpos %>%
  left_join(
    municipios %>% select(id_municip, municipio),
    by = "id_municip"
  )

dados_limpos %>%
  drop_na(municipio) %>%
  count(municipio, sort = TRUE)
##                   municipio    n
## 1                    RECIFE 8611
## 2   JABOATAO DOS GUARARAPES  283
## 3                    OLINDA  108
## 4                  PAULISTA   81
## 5                   IPOJUCA   12
## 6   CABO DE SANTO AGOSTINHO    8
## 7                  IGARASSU    7
## 8                CAMARAGIBE    6
## 9                   GRAVATA    4
## 10                ITAMARACA    2
## 11                 OURICURI    2
## 12     SAO LOURENCO DA MATA    2
## 13                 BEZERROS    1
## 14                    IPUBI    1
## 15                 LIMOEIRO    1

Criando variáveis úteis

Criando uma variável de faixa etária de acordo com a coluna de idade:

dados_limpos <- dados_limpos %>%
  mutate(
    faixa_etaria = case_when(
      idade < 12 ~ "Criança",
      idade < 18 ~ "Adolescente",
      idade < 60 ~ "Adulto",
      idade >= 60 ~ "Idoso",
      TRUE ~ "Ignorado"
    )
  )

Criando uma variável com o mês da notificação:

dados_limpos <- dados_limpos %>%
  mutate(
    mes_notificacao = month(dt_notific, label = TRUE)
  )

unique(dados_limpos$mes_notificacao)
##  [1] abr ago mar fev dez nov mai jan set jun out jul
## 12 Levels: jan < fev < mar < abr < mai < jun < jul < ago < set < ... < dez

Criando uma variável com a quantidade total de sintomas:

sintomas <- c(
  "febre", "mialgia", "cefaleia", "exantema",
  "vomito", "nausea", "dor_costas",
  "conjuntvit", "artralgia"
)

dados_limpos <- dados_limpos %>%
  mutate(
    total_sintomas = rowSums(select(., all_of(sintomas)) == 1,
                             na.rm = TRUE)
  )

head(dados_limpos$total_sintomas)
## [1] 3 3 9 1 4 3

Conjunto final

Após o processo de limpeza e transformação, o conjunto final permaneceu com as principais variáveis relevantes, mantendo a integridade dos registros originais e reduzindo a quantidade de atributos pouco informativos.

dim(dados_limpos)
## [1] 9187   68
datatable(
  dados_limpos %>%
    select(
      municipio,
      nm_bairro,
      sexo,
      idade,
      faixa_etaria,
      total_sintomas,
      evolucao_desc
    ) %>%
    slice_head(n = 100)
)

Análise exploratória dos dados

Após a etapa de preparação e limpeza dos dados, foi realizada uma análise exploratória com o objetivo de identificar padrões, tendências e relações relevantes presentes nas notificações de casos de dengue registradas em Recife durante o ano de 2025.

Esta etapa permite compreender melhor a estrutura do conjunto de dados, detectar comportamentos não evidentes inicialmente e gerar hipóteses a partir das informações observadas.

As análises realizadas abordam diferentes perspectivas dos dados, como:

  • evolução temporal das notificações;
  • distribuição geográfica dos casos;
  • perfil demográfico dos pacientes;
  • e a quantidade de sintomas por pacientes.

Evolução temporal dos casos

A análise temporal permite identificar padrões sazonais e possíveis períodos de maior transmissão da doença. Para isso, os casos foram agregados por semana de notificação.

casos_semana <- dados_limpos %>%
  count(sem_not)

casos_semana <- casos_semana %>%
  mutate(
    semana = as.numeric(substr(as.character(sem_not), 5, 6))
  )

grafico_semana <- ggplot(casos_semana,
                         aes(x = semana, y = n,
                             text = paste(
                               "Semana:", semana,
                               "<br>Casos:", n
                             ))) +
  geom_line(
    aes(group = 1),
    color = "#1F77B4",
    linewidth = 1.2
  ) +
  geom_point() +
  scale_x_continuous(
    breaks = seq(
      min(casos_semana$semana),
      max(casos_semana$semana),
      by = 2
    )
  ) +
  
  labs(
    x = "Semana",
    y = "Casos",
    title = "Evolução semanal dos casos notificados"
  ) +

  theme_minimal(base_size = 14) +

  theme(
    axis.title.y = element_text(
      angle = 90,
      face = "bold"
    )
  )

ggplotly(grafico_semana, tooltip = "text", width = 1200, height = 500)

Observa-se que a maior concentração de notificações ocorreu entre as semanas 32 e 42. Após esse período, nota-se uma tendência de redução gradual no número de notificações ao longo das semanas subsequentes.

Esse comportamento sugere a existência de sazonalidade na ocorrência da doença, possivelmente associada a fatores ambientais que favorecem a proliferação do mosquito transmissor, como períodos de maior precipitação e acúmulo de água parada. A identificação dessas semanas de pico pode auxiliar órgãos de saúde pública na antecipação de campanhas de prevenção e controle vetorial.

Além da análise por semana, também foi investigada a distribuição mensal das notificações para identificar possíveis períodos de maior incidência ao longo do ano.

casos_mes <- dados_limpos %>%
  count(mes_notificacao)

grafico_mes <- ggplot(casos_mes,
       aes(mes_notificacao, n,
           group = 1)) +
  geom_line(linewidth = 1.2) +
  geom_point(size = 3) +
  labs(
    title = "Casos por mes",
    x = "Mes",
    y = "Quantidade de casos"
  ) +
  theme_minimal()

ggplotly(grafico_mes, tooltip = "text", width = 700, height = 500)

A análise mensal evidencia que entre os meses de julho e outubro foi registrado o maior número de notificações. Em contrapartida, os meses de dezembro e maio registraram a menor quantidade de ocorrências.

Esse resultado reforça o padrão temporal observado anteriormente e permite identificar períodos críticos do ano para a transmissão da doença. O conhecimento desses períodos pode contribuir para o planejamento de ações preventivas.

Distribuição geográfica

A distribuição geográfica permite identificar regiões com maior concentração de notificações. Foram analisados os bairros com maior frequência de casos registrados.

Essa abordagem ajuda a identificar possíveis áreas prioritárias para vigilância epidemiológica e controle vetorial.

top_bairros <- dados_limpos %>%
  count(nm_bairro, sort = TRUE) %>%
  slice_head(n = 15)

ggplot(top_bairros,
       aes(x = reorder(nm_bairro, n),
           y = n)) +
  geom_col() +
  coord_flip() +
  labs(
    title = "Bairros com maior número de notificações",
    x = "Bairro",
    y = "Quantidade de Casos"
  ) +
  theme_minimal()

Os resultados mostram que os bairros de Cohab, Boa Viagem e Ibura concentraram os maiores números de notificações durante o período analisado. A concentração das notificações pode estar relacionada a fatores como densidade populacional, condições de saneamento, características ambientais e eficiência das ações de controle do vetor. A identificação dessas áreas prioritárias permite direcionar esforços de prevenção e monitoramento de forma mais eficiente.

Perfil demográfico dos casos

Foram analisadas características demográficas dos indivíduos notificados. Essas análises ajudam a identificar grupos populacionais mais afetados.

Analisando a distribuição etária dos pacientes:

ggplot(dados_limpos,
       aes(x = idade)) +
  geom_histogram(bins = 30) +
  scale_x_continuous(breaks = seq(0, max(dados_limpos$idade, na.rm = TRUE), by = 10)) +
  labs(
    title = "Distribuição da idade dos pacientes",
    x = "Idade",
    y = "Frequência"
  ) +
  theme_minimal()
## Warning: Removed 67 rows containing non-finite outside the scale range
## (`stat_bin()`).

A distribuição etária dos pacientes indica maior concentração de casos na faixa de 5 a 25 anos, sugerindo que indivíduos mais jovens representam a parcela mais afetada pelas notificações registradas.

Esse comportamento pode estar relacionado à maior exposição dessa população a ambientes externos, atividades laborais ou maior circulação em áreas urbanas. A compreensão do perfil etário predominante auxilia no direcionamento de campanhas educativas e ações de conscientização voltadas aos grupos mais vulneráveis.

Analisando a taxa de hospitalizações por faixa etária:

hospitalizacao_fx <- dados_limpos %>%
  filter(!is.na(hospitaliz)) %>%
  mutate(
    hospitalizado = ifelse(hospitaliz == 1, "Sim", "Não")
  ) %>%
  count(faixa_etaria, hospitalizado) %>%
  group_by(faixa_etaria) %>%
  mutate(prop = n / sum(n))

ggplot(hospitalizacao_fx,
       aes(x = faixa_etaria,
           y = prop,
           fill = hospitalizado)) +
  geom_col(position = "dodge") +
  scale_y_continuous(labels = scales::percent) +
  labs(
    title = "Proporção de hospitalizações por faixa etária",
    x = "Faixa Etária",
    y = "Proporção",
    fill = "Hospitalizado"
  ) +
  theme_minimal()

Observa-se que a faixa etária dos idosos apresentou a maior proporção de hospitalizações.

Esse resultado sugere que determinados grupos populacionais podem estar mais suscetíveis ao desenvolvimento de quadros clínicos que exigem acompanhamento hospitalar.

Quantidade de sintomas relatados

Como foi criada uma variável representando o número total de sintomas reportados por paciente, podemos avaliar o número de sintomas por paciente.

ggplot(
  dados_limpos,
  aes(total_sintomas)
) +
  geom_histogram(
    binwidth = 1
  ) +
  labs(
    title = "Numero de sintomas por paciente",
    x = "Total de sintomas",
    y = "Quantidade de pacientes"
  ) +
  theme_minimal()

Assim, observa-se forte concentração em torno de 3 sintomas por paciente.

Tabela interativa

Além das visualizações gráficas, foi construída uma tabela interativa contendo estatísticas resumidas por bairro.

tabela_bairros <- dados_limpos %>%
  group_by(nm_bairro) %>%
  summarise(
    Casos = n(),
    Idade_media = round(mean(idade, na.rm = TRUE),1),
    Sintomas_medios = round(mean(total_sintomas,
                                 na.rm = TRUE),1),
    Hospitalizacoes = sum(hospitaliz == 1,
                          na.rm = TRUE)
  ) %>%
  arrange(desc(Casos))

datatable(
  tabela_bairros,
  options = list(
    pageLength = 10,
    scrollX = TRUE
  ),
  caption = "Resumo por bairro"
)

Conclusão

Este trabalho teve como objetivo analisar os registros de dengue disponibilizados pela Prefeitura do Recife, buscando identificar padrões temporais, geográficos, demográficos e clínicos presentes nas notificações registradas ao longo de 2025.

Para abordar esse problema, foram utilizados dados públicos contendo notificações individuais dos casos registrados. Além da base principal, também foram integradas tabelas auxiliares contendo descrições dos agravos e informações geográficas dos municípios. A metodologia envolveu etapas de importação, limpeza, transformação e integração dos dados, além da criação de variáveis derivadas que possibilitaram análises mais detalhadas. Posteriormente, foram aplicadas técnicas de análise exploratória de dados utilizando gráficos e tabelas interativas.

Os resultados obtidos permitiram identificar diversos padrões relevantes. Observou-se concentração de casos em determinadas semanas, sugerindo comportamento sazonal das notificações. Também foram identificados bairros com maior número de registros, indicando possíveis regiões prioritárias para ações de vigilância epidemiológica. Em relação ao perfil dos pacientes, verificou-se predominância de casos em determinadas faixas etárias, além de diferenças nas taxas de hospitalização entre grupos.

As informações produzidas nesta análise podem ser utilizadas para direcionar campanhas preventivas e monitorar regiões críticas. Profissionais da saúde e pesquisadores podem utilizar os padrões identificados como apoio para estudos epidemiológicos futuros e acompanhamento do comportamento das arboviroses no município.

Apesar dos resultados obtidos, algumas limitações devem ser consideradas. A base de dados apresentou elevada quantidade de valores ausentes em determinadas variáveis. Também existem limitações relacionadas à qualidade do preenchimento das notificações, presença de possíveis inconsistências cadastrais e ausência de variáveis ambientais que poderiam enriquecer as análises, como dados climáticos, pluviométricos ou indicadores socioeconômicos.

Como possíveis melhorias, a análise poderia ser expandida com integração de novas bases de dados ambientais, aplicação de modelos preditivos para identificação de surtos, desenvolvimento de dashboards interativos com Shiny e utilização de técnicas de aprendizado de máquina para classificação de casos e detecção de padrões mais complexos.