---
title: "Trabalho de Bioestatística – PPGVIDA 2026"
subtitle: "Análise de Dengue Grave – SINAN/DENGBR2024 (Região Sul)"
author:
- name: "Aluno (a): ___________________________________________"
- name: "Aluno (a): ___________________________________________"
- name: "Aluno (a): ___________________________________________"
- name: "Aluno (a): ___________________________________________"
date: today
lang: pt
format:
html:
toc: true
toc-title: "Sumário"
toc-depth: 3
number-sections: true
theme: flatly
code-fold: true
code-tools: true
self-contained: true
fig-width: 9
fig-height: 6
execute:
echo: true
warning: false
message: false
---
```{r setup, include=FALSE}
# ============================================================
# PACOTES NECESSÁRIOS
# Instale caso não tenha: install.packages(c("tidyverse", "gtsummary",
# "ggplot2", "hnp", "MASS", "knitr", "kableExtra", "gt", "car",
# "broom", "scales", "patchwork", "ggcorrplot"))
# ============================================================
library(MASS) # Movido para cima para evitar conflito com o select()
library(tidyverse)
library(gtsummary)
library(ggplot2)
library(knitr)
library(kableExtra)
library(gt)
library(broom)
library(scales)
library(patchwork)
library(hnp)
```
---
# Introdução
Este relatório apresenta a análise bioestatística dos dados de **Dengue Grave** provenientes do SINAN (Sistema de Informação de Agravos de Notificação), base DENGBR2024. As análises contemplam estatísticas descritivas, visualização gráfica, análise de associação e modelagem estatística, seguindo os requisitos da disciplina de Bioestatística – MAVIDA09 do Programa de Pós-Graduação PPGVIDA.
---
# Questão 1 – Importação, Verificação e Estatísticas Descritivas
## Importação e verificação da base de dados
```{r importacao, message=FALSE, warning=FALSE}
# ============================================================
# IMPORTAÇÃO DA BASE DE DADOS
# Região Sul – SUL_DNG_GRV_24.csv
# ============================================================
dados <- read.csv("SUL_DNG_GRV_24.csv",
sep = ";",
header = TRUE,
stringsAsFactors = FALSE,
fileEncoding = "UTF-8")
# Garantir tipos corretos logo na importação
dados <- dados %>%
mutate(
IDADE = as.numeric(IDADE), # <<< CORREÇÃO AQUI
SEXO = as.factor(SEXO),
DESFECHO = as.factor(DESFECHO),
FEBRE = factor(FEBRE, levels = c(0,1), labels = c("Não","Sim")),
MIALGIA = factor(MIALGIA, levels = c(0,1), labels = c("Não","Sim")),
CEFALEIA = factor(CEFALEIA, levels = c(0,1), labels = c("Não","Sim")),
EXANTEMA = factor(EXANTEMA, levels = c(0,1), labels = c("Não","Sim")),
VOMITO = factor(VOMITO, levels = c(0,1), labels = c("Não","Sim")),
NAUSEA = factor(NAUSEA, levels = c(0,1), labels = c("Não","Sim")),
DOR_COSTAS = factor(DOR_COSTAS, levels = c(0,1), labels = c("Não","Sim")),
CONJUNTVIT = factor(CONJUNTVIT, levels = c(0,1), labels = c("Não","Sim")),
ARTRITE = factor(ARTRITE, levels = c(0,1), labels = c("Não","Sim")),
ARTRALGIA = factor(ARTRALGIA, levels = c(0,1), labels = c("Não","Sim")),
PETEQUIA_N = factor(PETEQUIA_N, levels = c(0,1), labels = c("Não","Sim")),
LEUCOPENIA = factor(LEUCOPENIA, levels = c(0,1), labels = c("Não","Sim")),
LACO = factor(LACO, levels = c(0,1), labels = c("Não","Sim")),
DOR_RETRO = factor(DOR_RETRO, levels = c(0,1), labels = c("Não","Sim")),
DIABETES = factor(DIABETES, levels = c(0,1), labels = c("Não","Sim")),
HEMATOLOG = factor(HEMATOLOG, levels = c(0,1), labels = c("Não","Sim")),
HEPATOPAT = factor(HEPATOPAT, levels = c(0,1), labels = c("Não","Sim")),
RENAL = factor(RENAL, levels = c(0,1), labels = c("Não","Sim")),
HIPERTENSAO = factor(HIPERTENSAO, levels = c(0,1), labels = c("Não","Sim")),
ACIDO_PEPT = factor(ACIDO_PEPT, levels = c(0,1), labels = c("Não","Sim")),
AUTO_IMUNE = factor(AUTO_IMUNE, levels = c(0,1), labels = c("Não","Sim"))
)
```
### Dimensões da base de dados
```{r dimensoes, message=FALSE, warning=FALSE}
cat("Número de linhas (observações):", nrow(dados), "\n")
cat("Número de colunas (variáveis):", ncol(dados), "\n")
glimpse(dados)
```
### Identificação de valores ausentes (NA) por variável
```{r missing, message=FALSE, warning=FALSE}
# Contagem e percentual de NA por variável
na_resumo <- dados %>%
summarise(across(everything(), ~ sum(is.na(.)))) %>%
pivot_longer(everything(), names_to = "Variável", values_to = "N_NA") %>%
mutate(
`Total` = nrow(dados),
`% NA` = round((N_NA / `Total`) * 100, 2),
`Completude (%)` = round(100 - `% NA`, 2)
)
na_resumo %>%
kbl(caption = "Tabela 1 – Completude das variáveis da base de dados",
align = "lcrrr") %>%
kable_styling(bootstrap_options = c("striped","hover","condensed"),
full_width = FALSE) %>%
column_spec(4, color = ifelse(na_resumo$`% NA` > 0, "red", "black"))
```
## Classificação das variáveis
```{r classificacao, message=FALSE, warning=FALSE}
# Quadro de classificação das variáveis
dicionario <- tribble(
~Ordem, ~Código, ~`Nome do Campo`, ~`Tipo`, ~`Natureza`,
1, "IDADE", "Idade do indivíduo (anos)", "Quantitativa", "Contínua",
2, "SEXO", "Sexo do indivíduo", "Qualitativa", "Nominal",
3, "DESFECHO", "Desfecho do indivíduo", "Qualitativa", "Nominal Binária",
4, "CONT_SINT", "Contagem de sinais clínicos", "Quantitativa", "Discreta",
5, "CONT_COMORB","Contagem de doenças pré-existentes", "Quantitativa", "Discreta",
6, "FEBRE", "Febre", "Qualitativa", "Nominal Binária",
7, "MIALGIA", "Mialgia", "Qualitativa", "Nominal Binária",
8, "CEFALEIA", "Cefaleia", "Qualitativa", "Nominal Binária",
9, "EXANTEMA", "Exantema", "Qualitativa", "Nominal Binária",
10, "VOMITO", "Vômito", "Qualitativa", "Nominal Binária",
11, "NAUSEA", "Náusea", "Qualitativa", "Nominal Binária",
12, "DOR_COSTAS", "Dor nas costas", "Qualitativa", "Nominal Binária",
13, "CONJUNTVIT", "Conjuntivite", "Qualitativa", "Nominal Binária",
14, "ARTRITE", "Artrite", "Qualitativa", "Nominal Binária",
15, "ARTRALGIA", "Artralgia", "Qualitativa", "Nominal Binária",
16, "PETEQUIA_N", "Petéquias", "Qualitativa", "Nominal Binária",
17, "LEUCOPENIA", "Leucopenia", "Qualitativa", "Nominal Binária",
18, "LACO", "Prova do laço", "Qualitativa", "Nominal Binária",
19, "DOR_RETRO", "Dor retro-orbital", "Qualitativa", "Nominal Binária",
20, "DIABETES", "Diabetes", "Qualitativa", "Nominal Binária",
21, "HEMATOLOG", "Doenças hematológicas", "Qualitativa", "Nominal Binária",
22, "HEPATOPAT", "Hepatopatias", "Qualitativa", "Nominal Binária",
23, "RENAL", "Doença renal crônica", "Qualitativa", "Nominal Binária",
24, "HIPERTENSAO","Hipertensão arterial", "Qualitativa", "Nominal Binária",
25, "ACIDO_PEPT", "Doença ácido-péptica", "Qualitativa", "Nominal Binária",
26, "AUTO_IMUNE", "Doenças autoimunes", "Qualitativa", "Nominal Binária"
)
dicionario %>%
kbl(caption = "Quadro 1 – Classificação das variáveis da base de dados") %>%
kable_styling(bootstrap_options = c("striped","hover","condensed"),
full_width = FALSE) %>%
row_spec(c(1,4,5), background = "#d4edda") %>%
row_spec(c(2,3), background = "#cce5ff")
```
**Legenda:** Verde = variáveis quantitativas | Azul = variáveis qualitativas nominais
## Tabela de medidas-resumo – gtsummary
```{r tabela_resumo, message=FALSE, warning=FALSE}
# Tabela única com TODAS as variáveis e medidas resumo adequadas
# Quantitativas → Mediana [IQR] e Média ± DP (verificar normalidade)
# Qualitativas → n (%)
dados %>%
dplyr::select(IDADE, SEXO, DESFECHO,
CONT_SINT, CONT_COMORB,
FEBRE, MIALGIA, CEFALEIA, EXANTEMA, VOMITO,
NAUSEA, DOR_COSTAS, CONJUNTVIT, ARTRITE, ARTRALGIA,
PETEQUIA_N, LEUCOPENIA, LACO, DOR_RETRO,
DIABETES, HEMATOLOG, HEPATOPAT, RENAL, HIPERTENSAO,
ACIDO_PEPT, AUTO_IMUNE) %>%
tbl_summary(
label = list(
IDADE ~ "Idade (anos)",
SEXO ~ "Sexo",
DESFECHO ~ "Desfecho",
CONT_SINT ~ "Contagem de sinais clínicos",
CONT_COMORB ~ "Contagem de comorbidades",
FEBRE ~ "Febre",
MIALGIA ~ "Mialgia",
CEFALEIA ~ "Cefaleia",
EXANTEMA ~ "Exantema",
VOMITO ~ "Vômito",
NAUSEA ~ "Náusea",
DOR_COSTAS ~ "Dor nas costas",
CONJUNTVIT ~ "Conjuntivite",
ARTRITE ~ "Artrite",
ARTRALGIA ~ "Artralgia",
PETEQUIA_N ~ "Petéquias",
LEUCOPENIA ~ "Leucopenia",
LACO ~ "Prova do laço",
DOR_RETRO ~ "Dor retro-orbital",
DIABETES ~ "Diabetes",
HEMATOLOG ~ "Doença hematológica",
HEPATOPAT ~ "Hepatopatia",
RENAL ~ "Doença renal crônica",
HIPERTENSAO ~ "Hipertensão arterial",
ACIDO_PEPT ~ "Doença ácido-péptica",
AUTO_IMUNE ~ "Doença autoimune"
),
statistic = list(
all_continuous() ~ "{mean} ± {sd} | Md={median} [{p25}; {p75}]",
all_categorical() ~ "{n} ({p}%)"
),
digits = list(
all_continuous() ~ 2,
all_categorical() ~ c(0, 1)
),
missing = "ifany",
missing_text = "Dado ausente (NA)"
) %>%
modify_header(label ~ "**Variável**") %>%
modify_caption("**Tabela 2 – Medidas-resumo das variáveis da base de dados (Dengue Grave – SINAN/2024)**") %>%
bold_labels() %>%
as_gt() %>%
tab_source_note("Fonte: SINAN – DENGBR2024. Contínuas: Média ± DP | Mediana [IQR]. Categóricas: n (%).")
```
## Interpretação das medidas-resumo
> **IDADE:** A distribuição etária deve ser interpretada a partir da mediana e do intervalo interquartílico (IQR), pois dados epidemiológicos tendem a apresentar assimetria. Uma mediana elevada (ex.: >50 anos) indica que indivíduos mais velhos predominam nos casos graves, o que é biologicamente plausível dado que comorbidades acumulam com a idade. A média e o desvio-padrão complementam a análise indicando a variabilidade total.
>
> **CONT_SINT e CONT_COMORB:** São variáveis de contagem (valores inteiros não negativos). A mediana indica o número típico de sinais/comorbidades por paciente; o IQR mostra a dispersão central. Valores elevados de CONT_COMORB associados ao desfecho óbito sustentariam a hipótese de que multimorbidade agrava o prognóstico da dengue grave.
>
> **Variáveis qualitativas binárias (sinais e comorbidades):** As frequências absolutas e relativas (n, %) descrevem a prevalência de cada sinal clínico e comorbidade na amostra. Por exemplo, se FEBRE = Sim em >90% dos casos, confirma-se o padrão esperado para dengue. Comorbidades como HIPERTENSÃO e DIABETES, se frequentes, apontam para um perfil de paciente de risco aumentado.
>
> **DESFECHO:** A proporção de Óbito_dengue vs. Outro_Evento é a medida epidemiológica central deste trabalho – a letalidade da dengue grave na região estudada.
---
# Questão 2 – Análise Gráfica das Variáveis
```{r paleta, include=FALSE}
# Paleta de cores acessível
cores <- c("#2E86AB", "#E84855", "#3BB273", "#F6AE2D", "#A23B72")
```
## Variáveis quantitativas
### IDADE
```{r graf_idade, message=FALSE, warning=FALSE, fig.cap="Figura 1 – Distribuição de frequência da Idade dos casos de Dengue Grave"}
p1 <- ggplot(dados, aes(x = IDADE)) +
geom_histogram(aes(y = after_stat(density)), bins = 30,
fill = cores[1], color = "white", alpha = 0.85) +
geom_density(color = cores[2], linewidth = 1.2) +
geom_vline(aes(xintercept = median(IDADE, na.rm = TRUE)),
color = cores[4], linetype = "dashed", linewidth = 1) +
annotate("text",
x = median(dados$IDADE, na.rm = TRUE) + 2,
y = Inf, vjust = 1.5,
label = paste0("Md = ", round(median(dados$IDADE, na.rm=TRUE),1)),
color = cores[4], size = 3.5) +
labs(title = "Distribuição da Idade – Dengue Grave",
subtitle = "Histograma com densidade estimada | linha tracejada = mediana",
x = "Idade (anos)", y = "Densidade") +
theme_minimal(base_size = 13)
p2 <- ggplot(dados, aes(y = IDADE)) +
geom_boxplot(fill = cores[1], alpha = 0.7, outlier.color = cores[2]) +
labs(title = "Boxplot da Idade",
y = "Idade (anos)", x = "") +
theme_minimal(base_size = 13) +
theme(axis.text.x = element_blank())
p1 + p2 + plot_layout(widths = c(3,1))
```
> **Interpretação:** O histograma com curva de densidade revela a forma da distribuição etária. Se assimétrica à direita (cauda longa em idades mais avançadas), a mediana é a medida de tendência central mais adequada. O boxplot complementa identificando valores atípicos (outliers). A presença de casos pediátricos (< 10 anos) ou idosos (> 70 anos) com óbito seria clinicamente relevante e merece destaque na análise.
### CONT_SINT
```{r graf_cont_sint, message=FALSE, warning=FALSE, fig.cap="Figura 2 – Distribuição da Contagem de Sinais Clínicos por indivíduo"}
dados %>%
count(CONT_SINT) %>%
ggplot(aes(x = factor(CONT_SINT), y = n)) +
geom_col(fill = cores[3], color = "white", alpha = 0.85) +
geom_text(aes(label = n), vjust = -0.5, size = 3.5) +
labs(title = "Contagem de Sinais Clínicos por Paciente",
subtitle = "Cada barra representa o número de pacientes com aquela quantidade de sinais",
x = "Número de sinais clínicos", y = "Frequência (n)") +
theme_minimal(base_size = 13)
```
> **Interpretação:** A contagem de sinais clínicos é uma variável de contagem discreta. O gráfico de barras exibe a distribuição de frequência de forma direta. Espera-se que a maioria dos casos graves apresente múltiplos sinais simultâneos. Pacientes com contagem zero podem indicar registro incompleto (NA informacional).
### CONT_COMORB
```{r graf_cont_comorb, message=FALSE, warning=FALSE, fig.cap="Figura 3 – Distribuição da Contagem de Comorbidades por indivíduo"}
dados %>%
count(CONT_COMORB) %>%
ggplot(aes(x = factor(CONT_COMORB), y = n)) +
geom_col(fill = cores[4], color = "white", alpha = 0.85) +
geom_text(aes(label = n), vjust = -0.5, size = 3.5) +
labs(title = "Contagem de Doenças Pré-Existentes (Comorbidades) por Paciente",
subtitle = "Distribuição de frequência da variável CONT_COMORB",
x = "Número de comorbidades", y = "Frequência (n)") +
theme_minimal(base_size = 13)
```
> **Interpretação:** Variável de contagem que expressa a carga de multimorbidade. Valores 0 representam pacientes sem comorbidade registrada. A presença de 2 ou mais comorbidades pode estar associada a maior risco de desfecho fatal, hipótese testada na Questão 3.
## Variáveis qualitativas – Sexo e Desfecho
```{r graf_sexo_desfecho, message=FALSE, warning=FALSE, fig.cap="Figura 4 – Distribuição de Sexo e Desfecho"}
g_sexo <- dados %>%
count(SEXO) %>%
mutate(prop = n / sum(n),
label = paste0(n, "\n(", percent(prop, accuracy=0.1),")")) %>%
ggplot(aes(x = SEXO, y = n, fill = SEXO)) +
geom_col(show.legend = FALSE, alpha = 0.85) +
geom_text(aes(label = label), vjust = -0.3, size = 3.5) +
scale_fill_manual(values = c(cores[1], cores[2])) +
labs(title = "Distribuição por Sexo",
x = "Sexo", y = "Frequência (n)") +
theme_minimal(base_size = 13)
g_des <- dados %>%
count(DESFECHO) %>%
mutate(prop = n / sum(n),
label = paste0(n, "\n(", percent(prop, accuracy=0.1),")")) %>%
ggplot(aes(x = reorder(DESFECHO, -n), y = n, fill = DESFECHO)) +
geom_col(show.legend = FALSE, alpha = 0.85) +
geom_text(aes(label = label), vjust = -0.3, size = 3.5) +
scale_fill_manual(values = c(cores[2], cores[3])) +
labs(title = "Distribuição por Desfecho",
x = "Desfecho", y = "Frequência (n)") +
theme_minimal(base_size = 13)
g_sexo + g_des
```
> **Interpretação:** Os gráficos de barras com frequência absoluta e relativa permitem avaliar a distribuição de sexo e desfecho. Uma proporção elevada de óbitos indica alta letalidade na amostra. Diferença entre sexos pode refletir desigualdades no acesso ao cuidado ou diferenças biológicas na gravidade da doença.
## Variáveis qualitativas – Sinais Clínicos
```{r graf_sinais, message=FALSE, warning=FALSE, fig.height=7, fig.cap="Figura 5 – Prevalência dos sinais clínicos nos casos de Dengue Grave"}
sinais_vars <- c("FEBRE","MIALGIA","CEFALEIA","EXANTEMA","VOMITO",
"NAUSEA","DOR_COSTAS","CONJUNTVIT","ARTRITE","ARTRALGIA",
"PETEQUIA_N","LEUCOPENIA","LACO","DOR_RETRO")
sinais_labels <- c("Febre","Mialgia","Cefaleia","Exantema","Vômito",
"Náusea","Dor nas costas","Conjuntivite","Artrite","Artralgia",
"Petéquias","Leucopenia","Prova do laço","Dor retro-orbital")
dados %>%
dplyr::select(all_of(sinais_vars)) %>%
pivot_longer(everything(), names_to = "Sinal", values_to = "Resultado") %>%
filter(!is.na(Resultado)) %>%
mutate(Sinal = factor(Sinal, levels = sinais_vars, labels = sinais_labels)) %>%
count(Sinal, Resultado) %>%
group_by(Sinal) %>%
mutate(prop = n / sum(n)) %>%
filter(Resultado == "Sim") %>%
ggplot(aes(x = reorder(Sinal, prop), y = prop)) +
geom_col(fill = cores[1], alpha = 0.85) +
geom_text(aes(label = percent(prop, accuracy=0.1)),
hjust = -0.1, size = 3.2) +
scale_y_continuous(labels = percent_format(), limits = c(0, 1.1)) +
coord_flip() +
labs(title = "Prevalência dos Sinais Clínicos – Dengue Grave",
subtitle = "Proporção de pacientes que apresentaram cada sinal clínico",
x = "", y = "Prevalência (%)") +
theme_minimal(base_size = 12)
```
> **Interpretação:** O gráfico de barras horizontais ordenado por prevalência revela quais sinais clínicos são mais comuns nos casos graves. Febre, mialgia, cefaleia e vômito tendem a ser os mais prevalentes. Sinais como petéquias e prova do laço positiva têm importância diagnóstica para dengue com alerta de gravidade, portanto sua frequência nesta amostra (dengue grave) merece atenção.
## Variáveis qualitativas – Comorbidades
```{r graf_comorbidades, message=FALSE, warning=FALSE, fig.cap="Figura 6 – Prevalência das comorbidades nos casos de Dengue Grave"}
comorb_vars <- c("DIABETES","HEMATOLOG","HEPATOPAT","RENAL",
"HIPERTENSAO","ACIDO_PEPT","AUTO_IMUNE")
comorb_labels <- c("Diabetes","Doença hematológica","Hepatopatia","Doença renal crônica",
"Hipertensão arterial","Doença ácido-péptica","Doença autoimune")
dados %>%
dplyr::select(all_of(comorb_vars)) %>%
pivot_longer(everything(), names_to = "Comorbidade", values_to = "Resultado") %>%
filter(!is.na(Resultado)) %>%
mutate(Comorbidade = factor(Comorbidade, levels = comorb_vars, labels = comorb_labels)) %>%
count(Comorbidade, Resultado) %>%
group_by(Comorbidade) %>%
mutate(prop = n / sum(n)) %>%
filter(Resultado == "Sim") %>%
ggplot(aes(x = reorder(Comorbidade, prop), y = prop)) +
geom_col(fill = cores[5], alpha = 0.85) +
geom_text(aes(label = percent(prop, accuracy=0.1)),
hjust = -0.1, size = 3.5) +
scale_y_continuous(labels = percent_format(), limits = c(0, 1.1)) +
coord_flip() +
labs(title = "Prevalência das Comorbidades – Dengue Grave",
subtitle = "Proporção de pacientes com cada doença pré-existente",
x = "", y = "Prevalência (%)") +
theme_minimal(base_size = 13)
```
> **Interpretação:** Hipertensão arterial e diabetes costumam ser as comorbidades mais prevalentes em séries de dengue grave no Brasil, refletindo o perfil epidemiológico da população adulta brasileira. A presença dessas condições pode comprometer a regulação hemodinâmica e imunológica, favorecendo a evolução para dengue grave e óbito.
---
# Questão 3 – Análise de Associação: DESFECHO vs. Variáveis
> A variável **DESFECHO** é binária (Obito_dengue vs. Outro_Evento) e constitui a variável coluna das tabelas cruzadas. Para cada associação, o teste estatístico é selecionado conforme a natureza das variáveis:
>
> - **Qualitativa × Qualitativa binária:** Teste Qui-quadrado de Pearson (ou Exato de Fisher quando frequências esperadas < 5)
> - **Quantitativa × Qualitativa binária:** Teste de Mann-Whitney U (não-paramétrico, dado que variáveis de contagem e IDADE tendem a não seguir normalidade perfeita em dados epidemiológicos)
```{r tab_cruzada, message=FALSE, warning=FALSE}
# Reordenar DESFECHO para que "Obito_dengue" apareça primeiro na tabela
dados <- dados %>%
mutate(DESFECHO = relevel(DESFECHO, ref = "Outro_Evento"))
dados %>%
dplyr::select(DESFECHO, IDADE, SEXO,
CONT_SINT, CONT_COMORB,
FEBRE, MIALGIA, CEFALEIA, EXANTEMA, VOMITO,
NAUSEA, DOR_COSTAS, CONJUNTVIT, ARTRITE, ARTRALGIA,
PETEQUIA_N, LEUCOPENIA, LACO, DOR_RETRO,
DIABETES, HEMATOLOG, HEPATOPAT, RENAL, HIPERTENSAO,
ACIDO_PEPT, AUTO_IMUNE) %>%
tbl_summary(
by = DESFECHO,
label = list(
IDADE ~ "Idade (anos)",
SEXO ~ "Sexo",
CONT_SINT ~ "Contagem de sinais clínicos",
CONT_COMORB ~ "Contagem de comorbidades",
FEBRE ~ "Febre",
MIALGIA ~ "Mialgia",
CEFALEIA ~ "Cefaleia",
EXANTEMA ~ "Exantema",
VOMITO ~ "Vômito",
NAUSEA ~ "Náusea",
DOR_COSTAS ~ "Dor nas costas",
CONJUNTVIT ~ "Conjuntivite",
ARTRITE ~ "Artrite",
ARTRALGIA ~ "Artralgia",
PETEQUIA_N ~ "Petéquias",
LEUCOPENIA ~ "Leucopenia",
LACO ~ "Prova do laço",
DOR_RETRO ~ "Dor retro-orbital",
DIABETES ~ "Diabetes",
HEMATOLOG ~ "Doença hematológica",
HEPATOPAT ~ "Hepatopatia",
RENAL ~ "Doença renal crônica",
HIPERTENSAO ~ "Hipertensão arterial",
ACIDO_PEPT ~ "Doença ácido-péptica",
AUTO_IMUNE ~ "Doença autoimune"
),
statistic = list(
all_continuous() ~ "{median} [{p25}; {p75}]",
all_categorical() ~ "{n} ({p}%)"
),
digits = list(
all_continuous() ~ 1,
all_categorical() ~ c(0,1)
),
missing = "no"
) %>%
add_p(
test = list(
all_continuous() ~ "wilcox.test", # Mann-Whitney
all_categorical() ~ "chisq.test" # Qui-quadrado (Fisher automático se freq<5)
),
pvalue_fun = function(x) style_pvalue(x, digits = 3)
) %>%
add_overall() %>%
bold_p(t = 0.05) %>%
modify_header(
label ~ "**Variável**",
stat_1 ~ "**Outro Evento** N = {n}",
stat_2 ~ "**Óbito por Dengue** N = {n}",
p.value ~ "**p-valor**"
) %>%
modify_caption("**Tabela 3 – Análise de associação das variáveis com o Desfecho (Dengue Grave – SINAN/2024)**") %>%
bold_labels() %>%
as_gt() %>%
tab_source_note("Contínuas: Mediana [IQR] – teste de Mann-Whitney. Categóricas: n (%) – teste Qui-quadrado ou Exato de Fisher.") %>%
tab_source_note("p-valores em negrito indicam associação estatisticamente significativa (α = 0,05).")
```
## Interpretação dos resultados da Tabela 3
> **Variáveis quantitativas (IDADE, CONT_SINT, CONT_COMORB):** O teste de Mann-Whitney avalia se as distribuições diferem entre os grupos de desfecho. Se p < 0,05, conclui-se que existe diferença estatisticamente significativa. Espera-se que pacientes com óbito apresentem maior mediana de IDADE e CONT_COMORB, indicando que indivíduos mais velhos e com maior carga de doenças pré-existentes têm pior prognóstico.
>
> **Variáveis qualitativas binárias:** O teste Qui-quadrado (ou Exato de Fisher) testa a independência entre o sinal/comorbidade e o desfecho. Uma associação significativa (p < 0,05) indica que a proporção do sinal difere entre óbitos e outros eventos. Por exemplo, se HIPERTENSÃO for significativamente mais prevalente no grupo óbito, isso sustenta que hipertensos têm maior risco de morte por dengue grave.
>
> **Atenção ao tamanho de efeito:** Além do p-valor, a magnitude das diferenças (diferença de medianas, razão de proporções) é clinicamente relevante. Um p-valor significativo com diferença pequena pode não ter relevância prática.
---
# Questão 4 – Relação Causal: CONT_SINT / CONT_COMORB em função de IDADE
## Justificativa estatística
> A suposição é que existe uma **relação causal** onde:
>
> - **Caso A:** CONT_SINT (contagem de sinais) depende de IDADE
> - **Caso B:** CONT_COMORB (contagem de comorbidades) depende de IDADE
>
> Ambas as variáveis resposta (CONT_SINT e CONT_COMORB) são **variáveis de contagem** (inteiros ≥ 0), o que invalida o uso de correlação de Pearson (que pressupõe normalidade e variáveis contínuas). As análises indicadas são:
>
> **Medida de associação:** Coeficiente de correlação de Spearman (ρ) – adequado para variáveis ordinais e de contagem com distribuições assimétricas, sem pressuposto de normalidade.
>
> **Hipóteses estatísticas:**
>
> H₀: ρ = 0 (não há correlação entre as variáveis)
> H₁: ρ ≠ 0 (existe correlação entre as variáveis)
>
> **Modelo sugerido:** Se o objetivo for modelar a relação preditiva, utiliza-se **Regressão de Poisson** (GLM com família Poisson e link logarítmico), pois a variável resposta é contagem. A regressão de Poisson é apresentada na Questão 5. Aqui focamos na análise correlacional e gráfica.
## CASO A – CONT_SINT em função de IDADE
### Correlação de Spearman
```{r corr_sint, message=FALSE, warning=FALSE}
cor_sint <- cor.test(dados$CONT_SINT, dados$IDADE,
method = "spearman",
exact = FALSE)
cat("=== CASO A: CONT_SINT ~ IDADE ===\n")
cat("Coeficiente de Spearman (rho):", round(cor_sint$estimate, 4), "\n")
cat("Estatística S:", round(cor_sint$statistic, 2), "\n")
cat("p-valor:", format(cor_sint$p.value, digits = 4), "\n")
```
### Gráfico de dispersão com linha de tendência – CASO A
```{r graf_sint_idade, message=FALSE, warning=FALSE, fig.cap="Figura 7 – Dispersão entre Contagem de Sinais Clínicos e Idade"}
ggplot(dados, aes(x = IDADE, y = CONT_SINT)) +
geom_jitter(alpha = 0.3, color = cores[1], width = 0.5, height = 0.3, size = 1.5) +
geom_smooth(method = "loess", color = cores[2], se = TRUE, linewidth = 1.2) +
geom_smooth(method = "lm", color = cores[4], se = FALSE,
linetype = "dashed", linewidth = 0.9) +
annotate("text", x = Inf, y = Inf, hjust = 1.1, vjust = 1.5,
label = paste0("ρ de Spearman = ",
round(cor_sint$estimate, 3),
"\np = ", format(cor_sint$p.value, digits=3)),
size = 4, color = "gray30") +
labs(title = "Contagem de Sinais Clínicos vs. Idade",
subtitle = "Curva LOESS (azul) e Regressão linear (amarela tracejada)",
x = "Idade (anos)", y = "Contagem de sinais clínicos") +
theme_minimal(base_size = 13)
```
> **Interpretação (CASO A):** O coeficiente de Spearman (ρ) indica a força e direção da associação monotônica entre IDADE e CONT_SINT. Se ρ ≈ 0 e p > 0,05, não há correlação significativa, sugerindo que a quantidade de sinais clínicos não varia sistematicamente com a idade. Se ρ > 0 e p < 0,05, pacientes mais velhos tendem a apresentar mais sinais. A curva LOESS (linha azul) revela a tendência não-linear dos dados sem impor um modelo rígido.
## CASO B – CONT_COMORB em função de IDADE
### Correlação de Spearman
```{r corr_comorb, message=FALSE, warning=FALSE}
cor_comorb <- cor.test(dados$CONT_COMORB, dados$IDADE,
method = "spearman",
exact = FALSE)
cat("=== CASO B: CONT_COMORB ~ IDADE ===\n")
cat("Coeficiente de Spearman (rho):", round(cor_comorb$estimate, 4), "\n")
cat("Estatística S:", round(cor_comorb$statistic, 2), "\n")
cat("p-valor:", format(cor_comorb$p.value, digits = 4), "\n")
```
### Gráfico de dispersão com linha de tendência – CASO B
```{r graf_comorb_idade, message=FALSE, warning=FALSE, fig.cap="Figura 8 – Dispersão entre Contagem de Comorbidades e Idade"}
ggplot(dados, aes(x = IDADE, y = CONT_COMORB)) +
geom_jitter(alpha = 0.3, color = cores[5], width = 0.5, height = 0.3, size = 1.5) +
geom_smooth(method = "loess", color = cores[2], se = TRUE, linewidth = 1.2) +
geom_smooth(method = "lm", color = cores[4], se = FALSE,
linetype = "dashed", linewidth = 0.9) +
annotate("text", x = Inf, y = Inf, hjust = 1.1, vjust = 1.5,
label = paste0("ρ de Spearman = ",
round(cor_comorb$estimate, 3),
"\np = ", format(cor_comorb$p.value, digits=3)),
size = 4, color = "gray30") +
labs(title = "Contagem de Comorbidades vs. Idade",
subtitle = "Curva LOESS (vermelho) e Regressão linear (amarela tracejada)",
x = "Idade (anos)", y = "Contagem de comorbidades") +
theme_minimal(base_size = 13)
```
> **Interpretação (CASO B):** É esperada uma correlação positiva (ρ > 0) entre IDADE e CONT_COMORB, pois doenças crônicas como hipertensão e diabetes acumulam-se ao longo da vida. Quanto maior o ρ e menor o p-valor, mais forte e consistente é essa associação na amostra. A curva LOESS permite identificar faixas etárias onde o acúmulo de comorbidades é mais acentuado (ex.: a partir dos 50-60 anos).
---
# Questão 5 – Regressão Logística: Predição do Desfecho (GLM)
## Justificativa do modelo
> **DESFECHO** é uma variável qualitativa binária (Óbito_dengue = sucesso; Outro_Evento = fracasso). Para modelar a probabilidade de óbito em função de variáveis explicativas mistas (contínuas e categóricas), o modelo adequado é a **Regressão Logística Binária** – um Modelo Linear Generalizado (GLM) com:
>
> - **Família:** Binomial
> - **Função de ligação:** Logit: log[p/(1-p)]
>
> As variáveis explicativas utilizadas são: IDADE, SEXO, CONT_SINT, CONT_COMORB, DIABETES e HIPERTENSAO.
## Preparação: DESFECHO como variável binária (0/1)
```{r prep_logistic, message=FALSE, warning=FALSE}
dados_modelo <- dados %>%
mutate(
DESFECHO_bin = ifelse(DESFECHO == "Obito_dengue", 1, 0),
SEXO_bin = ifelse(SEXO == "M", 1, 0), # 1=Masculino, 0=Feminino
DIABETES_bin = ifelse(DIABETES == "Sim", 1, 0),
HIPER_bin = ifelse(HIPERTENSAO == "Sim", 1, 0)
)
cat("Distribuição da variável resposta:\n")
table(dados_modelo$DESFECHO_bin) %>% print()
cat("\nProporção de óbitos:", round(mean(dados_modelo$DESFECHO_bin, na.rm=TRUE)*100, 2), "%\n")
```
## Ajuste do modelo de Regressão Logística
```{r modelo_logistico, message=FALSE, warning=FALSE}
modelo_log <- glm(
DESFECHO_bin ~ IDADE + SEXO_bin + CONT_SINT + CONT_COMORB + DIABETES_bin + HIPER_bin,
data = dados_modelo,
family = binomial(link = "logit")
)
summary(modelo_log)
```
## Tabela de resultados com Odds Ratio (OR) e IC 95%
# ============================================================
# Tabela de resultados com Odds Ratio (OR) e IC 95%
# ============================================================
or_tabela <- broom::tidy(modelo_log) %>%
filter(term != "(Intercept)") %>%
mutate(
OR = exp(estimate),
IC_inf = exp(estimate - 1.96 * std.error),
IC_sup = exp(estimate + 1.96 * std.error),
p.value_fmt = ifelse(p.value < 0.001, "< 0,001", round(p.value, 3)),
sig = case_when(
p.value < 0.001 ~ "***",
p.value < 0.01 ~ "**",
p.value < 0.05 ~ "*",
TRUE ~ ""
),
term = recode(term,
"IDADE" = "Idade (anos)",
"SEXO_bin" = "Sexo Masculino",
"CONT_SINT" = "Contagem de sinais clínicos",
"CONT_COMORB" = "Contagem de comorbidades",
"DIABETES_bin" = "Diabetes (Sim vs. Não)",
"HIPER_bin" = "Hipertensão (Sim vs. Não)"
)
) %>%
dplyr::select(
Variável = term,
OR,
`IC 95% Inf` = IC_inf,
`IC 95% Sup` = IC_sup,
`p-valor` = p.value_fmt,
`Sig.` = sig
)
kbl(or_tabela,
digits = 3,
caption = "Tabela 4 – Odds Ratio (OR) e IC 95% da Regressão Logística (Desfecho: Óbito por Dengue)",
align = "lrrrrc") %>%
kable_styling(
bootstrap_options = c("striped","hover","condensed"),
full_width = FALSE
) %>%
footnote(
general = "* p<0,05; ** p<0,01; *** p<0,001. OR > 1 indica risco; OR < 1 indica proteção.",
general_title = "Nota:"
)
caption = "Tabela 4 – Odds Ratio (OR) e IC 95% da Regressão Logística (Desfecho: Óbito por Dengue)",
align = "lrrrcc") %>%
kable_styling(bootstrap_options = c("striped","hover","condensed"), full_width = FALSE) %>%
footnote(general = "* p<0,05; ** p<0,01; *** p<0,001. OR > 1 indica fator de risco; OR < 1 indica fator protetor.",
general_title = "Nota:")
```
## Gráfico de florestamento (Forest Plot) dos OR
```{r forest_plot, message=FALSE, warning=FALSE, fig.cap="Figura 9 – Forest Plot dos Odds Ratio – Regressão Logística"}
tidy(modelo_log, conf.int = FALSE) %>%
mutate(
estimate = exp(estimate),
conf.low = exp(estimate - 1.96 * std.error),
conf.high = exp(estimate + 1.96 * std.error)
) %>%
filter(term != "(Intercept)") %>%
mutate(term = recode(term,
"IDADE" = "Idade (anos)",
"SEXO_bin" = "Sexo Masculino",
"CONT_SINT" = "N.º de sinais clínicos",
"CONT_COMORB" = "N.º de comorbidades",
"DIABETES_bin" = "Diabetes",
"HIPER_bin" = "Hipertensão")) %>%
ggplot(aes(x = estimate, y = reorder(term, estimate),
xmin = conf.low, xmax = conf.high,
color = p.value < 0.05)) +
geom_vline(xintercept = 1, linetype = "dashed", color = "gray50", linewidth = 0.8) +
geom_errorbarh(height = 0.25, linewidth = 0.9) +
geom_point(size = 4) +
scale_color_manual(values = c("gray60", cores[2]),
labels = c("Não significativo (p≥0,05)",
"Significativo (p<0,05)"),
name = "Significância") +
scale_x_log10() +
labs(title = "Forest Plot – Regressão Logística",
subtitle = "OR com IC 95% | Linha tracejada = OR nulo (1,0)",
x = "Odds Ratio (escala log)", y = "") +
theme_minimal(base_size = 13) +
theme(legend.position = "bottom")
```
## Gráfico HNP (Half-Normal Plot) – Diagnóstico do modelo
```{r hnp_plot, message=FALSE, warning=FALSE, fig.cap="Figura 10 – Gráfico HNP (Half-Normal Plot com envelope simulado) – Diagnóstico da Regressão Logística"}
# hnp avalia o ajuste do GLM via envelope simulado
# Pontos dentro do envelope: modelo bem ajustado
set.seed(42)
hnp(modelo_log,
sim = 99,
conf = 0.95,
print.on = TRUE,
main = "Half-Normal Plot com Envelope Simulado\nRegressão Logística – DESFECHO ~ IDADE + SEXO + CONT_SINT + CONT_COMORB + DIABETES + HIPERTENSÃO",
xlab = "Quantis da Meia-Normal",
ylab = "Resíduos Deviance (absolutos)")
```
## Qualidade do ajuste
```{r qualidade_ajuste, message=FALSE, warning=FALSE}
# Pseudo R² de McFadden
nulo <- modelo_log$null.deviance
ajust <- modelo_log$deviance
pseudo_r2 <- 1 - (ajust / nulo)
# AIC e BIC
aic_val <- AIC(modelo_log)
bic_val <- BIC(modelo_log)
# Desviance residual e graus de liberdade
cat("====================================================\n")
cat("Qualidade do Ajuste – Regressão Logística\n")
cat("====================================================\n")
cat("Pseudo R² de McFadden :", round(pseudo_r2, 4), "\n")
cat("AIC :", round(aic_val, 2), "\n")
cat("BIC :", round(bic_val, 2), "\n")
cat("Desviance nula :", round(nulo, 2),
"(gl =", modelo_log$df.null, ")\n")
cat("Desviance residual :", round(ajust, 2),
"(gl =", modelo_log$df.residual, ")\n")
cat("Teste de razão de veross.:", round(nulo - ajust, 2),
"(p =", round(pchisq(nulo - ajust,
df = modelo_log$df.null - modelo_log$df.residual,
lower.tail = FALSE), 4), ")\n")
```
## Curva ROC e AUC
```{r roc_curve, message=FALSE, warning=FALSE, fig.cap="Figura 11 – Curva ROC da Regressão Logística"}
# Probabilidades preditas
prob_pred <- predict(modelo_log, type = "response")
obs_bin <- dados_modelo$DESFECHO_bin[!is.na(prob_pred) &
!is.na(dados_modelo$DESFECHO_bin)]
prob_pred_clean <- prob_pred[!is.na(prob_pred) &
!is.na(dados_modelo$DESFECHO_bin)]
# Cálculo manual da curva ROC
roc_data <- tibble(
limiar = seq(0, 1, by = 0.01),
sens = sapply(seq(0,1,by=0.01), function(t)
sum(prob_pred_clean >= t & obs_bin == 1, na.rm=T) /
sum(obs_bin == 1, na.rm=T)),
espec = sapply(seq(0,1,by=0.01), function(t)
sum(prob_pred_clean < t & obs_bin == 0, na.rm=T) /
sum(obs_bin == 0, na.rm=T))
)
# AUC via trapézio
auc_val <- with(roc_data,
sum(diff(1 - espec) * (head(sens,-1) + tail(sens,-1))/2))
auc_val <- abs(auc_val)
ggplot(roc_data, aes(x = 1 - espec, y = sens)) +
geom_line(color = cores[1], linewidth = 1.2) +
geom_abline(slope = 1, intercept = 0, linetype = "dashed", color = "gray50") +
annotate("text", x = 0.6, y = 0.2,
label = paste0("AUC = ", round(auc_val, 3)),
size = 5, color = cores[2], fontface = "bold") +
labs(title = "Curva ROC – Regressão Logística",
subtitle = "Capacidade discriminatória do modelo",
x = "1 – Especificidade (Taxa de Falsos Positivos)",
y = "Sensibilidade (Taxa de Verdadeiros Positivos)") +
theme_minimal(base_size = 13)
```
## Interpretação completa dos resultados da Regressão Logística
> **Estrutura do modelo:** A regressão logística binária modela o logit da probabilidade de óbito por dengue grave em função das covariáveis IDADE, SEXO, CONT_SINT, CONT_COMORB, DIABETES e HIPERTENSÃO. O coeficiente de cada variável, quando exponenciado, fornece o **Odds Ratio (OR)** – a razão de chances de óbito associada a um incremento unitário na variável, mantendo as demais constantes.
>
> **Leitura dos OR:**
> - **OR > 1:** fator de risco (aumenta a chance de óbito)
> - **OR < 1:** fator protetor (diminui a chance de óbito)
> - **OR = 1:** sem associação
>
> **Exemplo de interpretação (valores hipotéticos):** Se OR_IDADE = 1,03 (IC 95%: 1,01–1,05; p < 0,05), conclui-se que, para cada ano adicional de vida, a chance de óbito aumenta em 3%, mantendo as demais variáveis constantes. Isso reforça que a idade é um fator de risco independente para a letalidade da dengue grave.
>
> **Diagnóstico via HNP:** O gráfico Half-Normal com envelope simulado avalia se os resíduos do modelo seguem o padrão esperado sob o modelo ajustado. Pontos dentro do envelope simulado indicam bom ajuste. Pontos sistematicamente fora sugerem que o modelo pode não estar capturando adequadamente a estrutura dos dados (possível superdispersão, subajuste ou variáveis omitidas).
>
> **Curva ROC e AUC:** A AUC (Área Sob a Curva ROC) quantifica a capacidade discriminatória do modelo. Valores de AUC próximos a 0,5 indicam modelo sem poder discriminatório (equivalente ao acaso); valores ≥ 0,7 indicam discriminação aceitável; ≥ 0,8, boa discriminação; e ≥ 0,9, excelente.
>
> **Pseudo R² de McFadden:** Análogo ao R² da regressão linear, mas para GLM. Valores entre 0,2 e 0,4 indicam ajuste satisfatório para modelos logísticos em dados epidemiológicos.
---
# Referências
- **Ministério da Saúde.** SINAN – Sistema de Informação de Agravos de Notificação. Base DENGBR2024. Brasília: SVS/MS, 2024.
- Sjoberg DD, et al. *gtsummary: Presentation-Ready Data Summary and Analytic Result Tables*. R package, 2024.
- Wickham H, et al. *Welcome to the tidyverse*. Journal of Open Source Software, 2019.
- Moral RA, Hinde J, Demétrio CGB. *Half-normal plots and overdispersed models in R: the hnp package*. Journal of Statistical Software, 2017.
- Hosmer DW, Lemeshow S, Sturdivant RX. *Applied Logistic Regression*. 3ª ed. Wiley, 2013.
---
*Relatório gerado em Quarto (R) – Disciplina Bioestatística MAVIDA09 / PPGVIDA 2026*