Introdução

Este relatório apresenta a análise estatística da aspiração broncopulmonar (ABP) em pacientes internados na unidade de gastrocirurgia.

Objetivos principais:

Dados e preparação

Importação da planilha

library(readxl)
library(dplyr)
library(janitor)
library(epitools)
library(knitr)
library(kableExtra)
library(tidyr)

caminho_arquivo <- "~/Desktop/GuilhermeABP.xlsx"

dados_abp <- read_excel(caminho_arquivo)

# Limpeza de nomes de variáveis
dados_abp <- dados_abp |>
  clean_names()

Preparação das variáveis de interesse

# Criação de variáveis derivadas
dados_abp <- dados_abp |>
  mutate(
    # ABP (0/1) e fator
    abp = abp_evento,
    abp_fac = factor(abp_evento, labels = c("Sem ABP", "Com ABP")),

    # Óbito (0/1) e fator
    obito = ifelse(desfecho == "Óbito", 1, 0),
    obito_fac = factor(obito, labels = c("Sem óbito", "Óbito")),

    # Risco gastrointestinal (qualquer)
    gi_risco_qualquer = ifelse(riscos_gastro != "Não" & !is.na(riscos_gastro), 1, 0),
    gi_risco_qualquer_fac = factor(gi_risco_qualquer,
                                   labels = c("Sem risco GI", "Com risco GI")),

    # Sexo masculino (0/1)
    male = ifelse(genero == "Masculino", 1, 0)
  )

# Verificações básicas
n_total <- nrow(dados_abp)
tab_abp <- table(dados_abp$abp_fac)
kable(as.data.frame(tab_abp), col.names = c("Grupo", "N"),
      caption = "Distribuição de ABP na amostra")
Distribuição de ABP na amostra
Grupo N
Sem ABP 253
Com ABP 34
library(dplyr)
library(stringr)

# Agrupamento dos antecedentes pessoais
dados_abp <- dados_abp |>
  mutate(
    has = ifelse(str_detect(antecedentes_pessoais, regex("HAS|hipertens", ignore_case = TRUE)), 1, 0),
    dm = ifelse(str_detect(antecedentes_pessoais, regex("DM|diabet", ignore_case = TRUE)), 1, 0),
    dislipidemia = ifelse(str_detect(antecedentes_pessoais, regex("dislipid", ignore_case = TRUE)), 1, 0),
    cardio = ifelse(str_detect(antecedentes_pessoais, regex("cardio|AVE|infarto", ignore_case = TRUE)), 1, 0),
    pulmao = ifelse(str_detect(antecedentes_pessoais, regex("asma|DPOC|pulmon", ignore_case = TRUE)), 1, 0),
    renal = ifelse(str_detect(antecedentes_pessoais, regex("renal|DRC|IRA", ignore_case = TRUE)), 1, 0),
    hepatica = ifelse(str_detect(antecedentes_pessoais, regex("hepat|cirrose|VHC", ignore_case = TRUE)), 1, 0),
    psiq = ifelse(str_detect(antecedentes_pessoais, regex("psiq|esquiz|depress", ignore_case = TRUE)), 1, 0),
    tabagismo = ifelse(str_detect(antecedentes_pessoais, regex("tabag", ignore_case = TRUE)), 1, 0),
    etilismo = ifelse(str_detect(antecedentes_pessoais, regex("etil|alcool", ignore_case = TRUE)), 1, 0),
    obesidade = ifelse(str_detect(antecedentes_pessoais, regex("obes", ignore_case = TRUE)), 1, 0),
    cirurgias_previas = ifelse(str_detect(antecedentes_pessoais, regex("cirurg", ignore_case = TRUE)), 1, 0),
    nenhum = ifelse(str_detect(antecedentes_pessoais, regex("^Nenhum$", ignore_case = TRUE)), 1, 0),

    # Agrupamento do HD (diagnóstico de entrada)
    hd_figado = ifelse(str_detect(hd, regex("fígado|figado|hepatic|cirrose|hepatite", ignore_case = TRUE)), 1, 0),
    hd_biliar = ifelse(str_detect(hd, regex("colecist|colelit|coledoc|colang", ignore_case = TRUE)), 1, 0),
    hd_pancreas = ifelse(str_detect(hd, regex("pancrea", ignore_case = TRUE)), 1, 0),
    hd_neoplasia = ifelse(str_detect(hd, regex("neo|carcin|tumor|adenocarc", ignore_case = TRUE)), 1, 0),
    hd_posop = ifelse(str_detect(hd, regex("PO \\(|POT \\(|gastrect|esofagect|fundop|laparot|duodenopancreatect", ignore_case = TRUE)), 1, 0),
    hd_hernia = ifelse(str_detect(hd, regex("hern", ignore_case = TRUE)), 1, 0),
    hd_esofago_refluxo = ifelse(str_detect(hd, regex("acal|reflux|Nissen|megaesof", ignore_case = TRUE)), 1, 0)
  )

Resultados

1. Caracterização da amostra

1.1 Idade

idade_resumo <- dados_abp |>
  summarise(
    n = n(),
    media = mean(idade, na.rm = TRUE),
    dp = sd(idade, na.rm = TRUE),
    mediana = median(idade, na.rm = TRUE),
    q1 = quantile(idade, 0.25, na.rm = TRUE),
    q3 = quantile(idade, 0.75, na.rm = TRUE),
    min = min(idade, na.rm = TRUE),
    max = max(idade, na.rm = TRUE)
  )

kable(idade_resumo, digits = 2,
      caption = "Resumo descritivo da idade (anos)")
Resumo descritivo da idade (anos)
n media dp mediana q1 q3 min max
287 54.3 14.79 56 43.5 65 18 94

1.2 Sexo

tab_sexo <- table(dados_abp$genero)
prop_sexo <- prop.table(tab_sexo)

kable(cbind(
  Sexo = names(tab_sexo),
  N = as.vector(tab_sexo),
  Proporcao = round(100 * as.vector(prop_sexo), 1)
),
col.names = c("Sexo", "N", "%"),
caption = "Distribuição de sexo na amostra")
Distribuição de sexo na amostra
Sexo N %
Feminino 150 52.3
Masculino 137 47.7

1.3 Desfechos hospitalares

tab_desfecho <- table(dados_abp$desfecho)
prop_desfecho <- prop.table(tab_desfecho)

kable(cbind(
  Desfecho = names(tab_desfecho),
  N = as.vector(tab_desfecho),
  Proporcao = round(100 * as.vector(prop_desfecho), 1)
),
col.names = c("Desfecho", "N", "%"),
caption = "Distribuição dos desfechos hospitalares")
Distribuição dos desfechos hospitalares
Desfecho N %
Alta 274 95.5
Óbito 11 3.8
Transferência Externa 2 0.7

1.4 Risco gastrointestinal (qualquer)

tab_gi <- table(dados_abp$gi_risco_qualquer_fac)
prop_gi <- prop.table(tab_gi)

kable(cbind(
  Risco_GI = names(tab_gi),
  N = as.vector(tab_gi),
  Proporcao = round(100 * as.vector(prop_gi), 1)
),
col.names = c("Risco GI", "N", "%"),
caption = "Distribuição de risco gastrointestinal (qualquer)")
Distribuição de risco gastrointestinal (qualquer)
Risco GI N %
Sem risco GI 111 38.7
Com risco GI 176 61.3

1.5 Grupo cirúrgico

tab_grupo <- table(dados_abp$grupo_cx)
prop_grupo <- prop.table(tab_grupo)

kable(cbind(
  Grupo_Cx = names(tab_grupo),
  N = as.vector(tab_grupo),
  Proporcao = round(100 * as.vector(prop_grupo), 1)
),
col.names = c("Grupo cirúrgico", "N", "%"),
caption = "Distribuição dos grupos cirúrgicos")
Distribuição dos grupos cirúrgicos
Grupo cirúrgico N %
Clínico / Sem Intervenção 75 26.1
Colorretal / Prócto 2 0.7
Hepatobiliar / Transplante 30 10.5
Parede Abdominal / Hérnias 7 2.4
Procedimentos Intervencionistas (Não Cirúrgicos) 65 22.6
Trato Gastrointestinal Alto 108 37.6

1.6 Tempos de internação, UTI e enfermaria

tempos_resumo <- dados_abp |>
  summarise(
    mediana_dias_internacao = median(dias_internacao, na.rm = TRUE),
    q1_dias_internacao = quantile(dias_internacao, 0.25, na.rm = TRUE),
    q3_dias_internacao = quantile(dias_internacao, 0.75, na.rm = TRUE),
    mediana_dias_uti = median(dias_uti, na.rm = TRUE),
    q1_dias_uti = quantile(dias_uti, 0.25, na.rm = TRUE),
    q3_dias_uti = quantile(dias_uti, 0.75, na.rm = TRUE),
    mediana_dias_enfermaria = median(dias_enfermaria, na.rm = TRUE),
    q1_dias_enfermaria = quantile(dias_enfermaria, 0.25, na.rm = TRUE),
    q3_dias_enfermaria = quantile(dias_enfermaria, 0.75, na.rm = TRUE)
  )

kable(tempos_resumo, digits = 2,
      caption = "Resumo dos tempos de internação, UTI e enfermaria (medianas e quartis)")
Resumo dos tempos de internação, UTI e enfermaria (medianas e quartis)
mediana_dias_internacao q1_dias_internacao q3_dias_internacao mediana_dias_uti q1_dias_uti q3_dias_uti mediana_dias_enfermaria q1_dias_enfermaria q3_dias_enfermaria
6 4 12 0 0 0 4 3 9

1.7 Antecedentes pessoais agrupados

Os antecedentes pessoais foram reagrupados em grandes categorias clínicas (hipertensão arterial sistêmica, diabetes mellitus, dislipidemia, doenças cardiovasculares, pulmonares, renais, hepáticas, transtornos psiquiátricos, tabagismo, etilismo, obesidade, cirurgias prévias e ausência de antecedentes). A tabela abaixo apresenta o número e a proporção de pacientes em cada categoria.

Antecedentes pessoais agrupados por categoria clínica
Categoria N %
Cirurgias prévias 176 61.3
Hipertensão arterial sistêmica (HAS) 115 40.1
Tabagismo (atual ou prévio) 75 26.1
Etilismo (atual ou prévio) 57 19.9
Diabetes mellitus (DM) 56 19.5
Dislipidemia 29 10.1
Doenças cardiovasculares 26 9.1
Sem antecedentes relatados 26 9.1
Obesidade 25 8.7
Transtornos psiquiátricos 21 7.3
Doenças pulmonares 12 4.2
Doença renal 12 4.2
Doença hepática 11 3.8

1.8 Diagnóstico de entrada (HD) – categorias agrupadas

library(dplyr)
library(stringr)
library(knitr)

# Garantir recodificação (se já fez antes, não tem problema repetir)
dados_abp <- dados_abp |>
  mutate(
    hd_figado = ifelse(str_detect(hd, regex("fígado|figado|hepatic|cirrose|hepatite", ignore_case = TRUE)), 1, 0),
    hd_biliar = ifelse(str_detect(hd, regex("colecist|colelit|coledoc|colang", ignore_case = TRUE)), 1, 0),
    hd_pancreas = ifelse(str_detect(hd, regex("pancrea", ignore_case = TRUE)), 1, 0),
    hd_neoplasia = ifelse(str_detect(hd, regex("neo|carcin|tumor|adenocarc", ignore_case = TRUE)), 1, 0),
    hd_posop = ifelse(str_detect(hd, regex("PO \\(|POT \\(|gastrect|esofagect|fundop|laparot|duodenopancreatect|colectom|herniorrafia|gastroplastia", ignore_case = TRUE)), 1, 0),
    hd_hernia = ifelse(str_detect(hd, regex("hern", ignore_case = TRUE)), 1, 0),
    hd_esofago_refluxo = ifelse(str_detect(hd, regex("acal|reflux|Nissen|megaesof|esofag", ignore_case = TRUE)), 1, 0)
  )

# Resumo em formato "comprido" (1 linha por categoria)
hd_sintetico <- tibble::tibble(
  `Categoria clínica` = c(
    "Fígado",
    "Biliar",
    "Pâncreas",
    "Neoplasias",
    "Pós-operatório",
    "Hérnias",
    "Esôfago / Refluxo / Acalásia"
  ),
  N = c(
    sum(dados_abp$hd_figado, na.rm = TRUE),
    sum(dados_abp$hd_biliar, na.rm = TRUE),
    sum(dados_abp$hd_pancreas, na.rm = TRUE),
    sum(dados_abp$hd_neoplasia, na.rm = TRUE),
    sum(dados_abp$hd_posop, na.rm = TRUE),
    sum(dados_abp$hd_hernia, na.rm = TRUE),
    sum(dados_abp$hd_esofago_refluxo, na.rm = TRUE)
  )
)

kable(
  hd_sintetico,
  caption = "Diagnóstico de entrada (HD) agrupado por categorias clínicas",
  align = c("l", "c")
)
Diagnóstico de entrada (HD) agrupado por categorias clínicas
Categoria clínica N
Fígado 79
Biliar 93
Pâncreas 20
Neoplasias 85
Pós-operatório 177
Hérnias 9
Esôfago / Refluxo / Acalásia 30

2.2 Tempo de internação (H1)

internacao_por_abp <- dados_abp |>
  group_by(abp_fac) |>
  summarise(
    n = n(),
    mediana = median(dias_internacao, na.rm = TRUE),
    q1 = quantile(dias_internacao, 0.25, na.rm = TRUE),
    q3 = quantile(dias_internacao, 0.75, na.rm = TRUE)
  )

kable(internacao_por_abp, digits = 2,
      caption = "Tempo de internação por grupo de ABP (mediana e IIQ)")
Tempo de internação por grupo de ABP (mediana e IIQ)
abp_fac n mediana q1 q3
Sem ABP 253 5 4 11.00
Com ABP 34 13 7 31.25
teste_internacao <- wilcox.test(dias_internacao ~ abp, data = dados_abp)
teste_internacao
## 
##  Wilcoxon rank sum test with continuity correction
## 
## data:  dias_internacao by abp
## W = 2284.5, p-value = 8.227e-06
## alternative hypothesis: true location shift is not equal to 0

2.3 Dias de UTI e enfermaria

uti_por_abp <- dados_abp |>
  group_by(abp_fac) |>
  summarise(
    mediana_uti = median(dias_uti, na.rm = TRUE),
    q1_uti = quantile(dias_uti, 0.25, na.rm = TRUE),
    q3_uti = quantile(dias_uti, 0.75, na.rm = TRUE),
    mediana_enf = median(dias_enfermaria, na.rm = TRUE),
    q1_enf = quantile(dias_enfermaria, 0.25, na.rm = TRUE),
    q3_enf = quantile(dias_enfermaria, 0.75, na.rm = TRUE)
  )

kable(uti_por_abp, digits = 2,
      caption = "Dias de UTI e enfermaria por grupo de ABP (mediana e IIQ)")
Dias de UTI e enfermaria por grupo de ABP (mediana e IIQ)
abp_fac mediana_uti q1_uti q3_uti mediana_enf q1_enf q3_enf
Sem ABP 0 0 0.00 4 2 9.00
Com ABP 2 0 9.25 7 4 13.75
teste_uti <- wilcox.test(dias_uti ~ abp, data = dados_abp)
teste_enf <- wilcox.test(dias_enfermaria ~ abp, data = dados_abp)

teste_uti
## 
##  Wilcoxon rank sum test with continuity correction
## 
## data:  dias_uti by abp
## W = 2535, p-value = 2.876e-07
## alternative hypothesis: true location shift is not equal to 0
teste_enf
## 
##  Wilcoxon rank sum test with continuity correction
## 
## data:  dias_enfermaria by abp
## W = 3025, p-value = 0.004719
## alternative hypothesis: true location shift is not equal to 0

2.4 Mortalidade e ABP

tab_morte <- table(dados_abp$abp_fac, dados_abp$obito_fac)
kable(tab_morte, caption = "Tabela cruzada: ABP x óbito")
Tabela cruzada: ABP x óbito
Sem óbito Óbito
Sem ABP 248 5
Com ABP 28 6
chisq_morte <- chisq.test(tab_morte, correct = TRUE)
chisq_morte
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  tab_morte
## X-squared = 15.944, df = 1, p-value = 6.525e-05
or_morte <- oddsratio(tab_morte)
or_morte
## $data
##          
##           Sem óbito Óbito Total
##   Sem ABP       248     5   253
##   Com ABP        28     6    34
##   Total         276    11   287
## 
## $measure
##          odds ratio with 95% C.I.
##           estimate    lower    upper
##   Sem ABP  1.00000       NA       NA
##   Com ABP 10.40836 2.876604 39.44726
## 
## $p.value
##          two-sided
##             midp.exact fisher.exact   chi.square
##   Sem ABP           NA           NA           NA
##   Com ABP 0.0005815753 0.0005394042 7.870005e-06
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "median-unbiased estimate & mid-p exact CI"

3. Associação entre ABP e risco gastrointestinal (H2)

tab_gi_abp <- table(dados_abp$abp_fac, dados_abp$gi_risco_qualquer_fac)
kable(tab_gi_abp, caption = "Tabela cruzada: ABP x risco gastrointestinal (qualquer)")
Tabela cruzada: ABP x risco gastrointestinal (qualquer)
Sem risco GI Com risco GI
Sem ABP 105 148
Com ABP 6 28
chisq_gi <- chisq.test(tab_gi_abp, correct = TRUE)
chisq_gi
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  tab_gi_abp
## X-squared = 6.2206, df = 1, p-value = 0.01263
or_gi <- oddsratio(tab_gi_abp)
or_gi
## $data
##          
##           Sem risco GI Com risco GI Total
##   Sem ABP          105          148   253
##   Com ABP            6           28    34
##   Total            111          176   287
## 
## $measure
##          odds ratio with 95% C.I.
##           estimate    lower    upper
##   Sem ABP 1.000000       NA       NA
##   Com ABP 3.236004 1.370868 9.023813
## 
## $p.value
##          two-sided
##            midp.exact fisher.exact  chi.square
##   Sem ABP          NA           NA          NA
##   Com ABP 0.006101355  0.008056401 0.007326186
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "median-unbiased estimate & mid-p exact CI"

4. Associação entre ABP e grupo cirúrgico (exploratória)

tab_grupo_abp <- table(dados_abp$abp_fac, dados_abp$grupo_cx)
kable(tab_grupo_abp, caption = "Tabela cruzada: ABP x grupo cirúrgico")
Tabela cruzada: ABP x grupo cirúrgico
Clínico / Sem Intervenção Colorretal / Prócto Hepatobiliar / Transplante Parede Abdominal / Hérnias Procedimentos Intervencionistas (Não Cirúrgicos) Trato Gastrointestinal Alto
Sem ABP 71 2 24 7 58 91
Com ABP 4 0 6 0 7 17
chisq_grupo <- chisq.test(tab_grupo_abp)
chisq_grupo
## 
##  Pearson's Chi-squared test
## 
## data:  tab_grupo_abp
## X-squared = 7.8063, df = 5, p-value = 0.1672

Observação: caso o p-valor seja ≥ 0,05, considera-se que não houve associação estatisticamente significativa entre grupo cirúrgico e ABP na amostra.

5. Regressão logística: fatores associados à ABP

5.1 Modelo multivariado

modelo <- glm(
  abp ~ idade + male + gi_risco_qualquer,
  family = binomial,
  data = dados_abp
)

summary(modelo)
## 
## Call:
## glm(formula = abp ~ idade + male + gi_risco_qualquer, family = binomial, 
##     data = dados_abp)
## 
## Coefficients:
##                   Estimate Std. Error z value Pr(>|z|)    
## (Intercept)       -5.45064    1.00398  -5.429 5.67e-08 ***
## idade              0.03493    0.01491   2.343   0.0191 *  
## male               1.00472    0.40865   2.459   0.0139 *  
## gi_risco_qualquer  1.18487    0.47730   2.482   0.0130 *  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 208.86  on 286  degrees of freedom
## Residual deviance: 186.20  on 283  degrees of freedom
## AIC: 194.2
## 
## Number of Fisher Scoring iterations: 5
or_ci <- exp(cbind(OR = coef(modelo), confint(modelo)))
kable(or_ci, digits = 3, caption = "Razões de chances (OR) ajustadas com IC95%")
Razões de chances (OR) ajustadas com IC95%
OR 2.5 % 97.5 %
(Intercept) 0.004 0.001 0.027
idade 1.036 1.007 1.068
male 2.731 1.257 6.332
gi_risco_qualquer 3.270 1.364 9.136

5.2 Interpretação

  • Idade: OR > 1 indica aumento da chance de ABP com o avanço da idade.
  • Sexo masculino (male): OR > 1 indica maior chance de ABP em homens comparados a mulheres.
  • Risco gastrointestinal: OR > 1 indica maior chance de ABP entre pacientes com algum risco GI documentado.

A significância estatística deve ser interpretada a partir dos p-valores no summary(modelo) e dos IC95% (intervalos que não incluem 1 sugerem associação estatisticamente significativa).

Conclusões

Todos os procedimentos estatísticos foram realizados de forma íntegra e reprodutível no software R (versão 4.4.1), utilizando o ambiente RStudio 2025.05.0+496 ‘Mariposa Orchid’ e Quarto 1.6.42.

Para esclarecimentos adicionais ou solicitações complementares, permaneço à disposição pelo e-mail: