Bloqueio da bainha dos músculos retos abdominais guiado por ultrassom em hernioplastias umbilicais ambulatoriais: uma análise comparativa do uso de clonidina como adjuvante — estudo clínico prospectivo randomizado

1 INTRODUÇÃO

As hérnias umbilicais constituem uma das indicações cirúrgicas mais prevalentes, sendo frequentemente tratadas em regime ambulatorial. O bloqueio da bainha dos músculos retos abdominais (BMRA) guiado por ultrassom tem se destacado como técnica anestésica regional promissora para analgesia perioperatória nesses procedimentos. A clonidina, um agonista α2-adrenérgico, é investigada como adjuvante aos anestésicos locais por potencializar o efeito analgésico e reduzir o consumo de opioides, porém sua eficácia e segurança em BMRA para hernioplastia ambulatorial permanecem pouco estabelecidas.

2 Diagrama CONSORT 2025

O fluxograma apresenta todas as etapas do ensaio clínico: número de indivíduos avaliados para elegibilidade, razões de exclusão, número de participantes randomizados, distribuição entre os grupos de intervenção e controle, perdas e exclusões durante o seguimento e quantidade de participantes incluídos na análise estatística final, em conformidade com as recomendações do CONSORT 2025.

3 OBJETIVOS

Objetivo Geral: Comparar a eficácia da adição de clonidina à solução de anestésico local versus anestésico local isolado no bloqueio da bainha dos músculos retos abdominais guiado por ultrassom, em pacientes submetidos a hernioplastia umbilical ambulatorial, quanto à redução do consumo de opioides intra e pós-operatórios (até 48 horas), bem como à diminuição dos escores da escala visual numérica da dor (EVN) em repouso e em movimento, avaliados na alta da sala de recuperação pós-anestésica (SRPA), 24h e 48h após a cirurgia.

Objetivos Específicos:

  1. Avaliar a qualidade da recuperação dos pacientes utilizando o questionário de Qualidade de Recuperação (Quality of Recovery, QoR-15) nas avaliações de 24 e 48h após a cirurgia;
  2. Avaliar as incidências de complicações, incluindo bradicardia, náuseas e vômitos pós-operatórios, conversão para anestesia geral, sedação residual excessiva (avaliada pela Escala de Agitação e sedação de Richmond - RASS), necessidade de internação hospitalar, hematoma de parede abdominal e infecção.

4 Descrição do conjunto de dados

O conjunto RSB_clonidine_39 corresponde ao banco do estudo comparando bloqueio da bainha dos retos (BMRA) e BMRA-CLO (clonidina). As variáveis contemplam dados demográficos e clínicos relevantes (idade, sexo, peso, altura, IMC, ASA e comorbidades), com alocação em randomization_group.

Estratificação: randomization_groupBMRA = 0; BMRA-CLO = 1.

# Procura o CSV em locais comuns; edite a lista se necessário
candidatos <- c(
  "RSB_clonidine_39.csv",
  "C:/RSB_clonidine_39.csv",
  "C:/Users/T-GAMER/Downloads/RSB_clonidine_39.csv",
  file.path(Sys.getenv("USERPROFILE"), "Downloads", "RSB_clonidine_39.csv")
)
data_path <- candidatos[file.exists(candidatos)][1]
if (is.na(data_path))
  stop("CSV não encontrado. Locais procurados:\n", paste(" -", candidatos, collapse = "\n"))
message("Lendo: ", normalizePath(data_path))
dados <- readr::read_csv(data_path, show_col_types = FALSE)
tem_col <- function(nm) nm %in% names(dados)

# Casa nomes de colunas ignorando acentos, caixa e pontuação
norm_nm <- function(s) gsub("[^a-z]", "", tolower(iconv(s, to = "ASCII//TRANSLIT")))
get_bin_factor <- function(cands) {
  hit <- names(dados)[norm_nm(names(dados)) %in% norm_nm(cands)]
  if (length(hit)) factor(dados[[hit[1]]], levels = c(0,1), labels = c("Nao","Sim"))
  else factor(rep(NA_integer_, nrow(dados)), levels = c(0,1), labels = c("Nao","Sim"))
}

# QoR-15 recalculado a partir dos 15 itens (escore canônico). Itens sem sufixo = SRPA.
soma_qor <- function(suf = "") {
  it <- c(paste0("qor_a", 1:10, suf), paste0("qor_b", 1:5, suf))
  it <- it[it %in% names(dados)]
  if (length(it) != 15) return(rep(NA_real_, nrow(dados)))
  rowSums(dados[, it])
}

dados <- dados %>%
  mutate(
    id    = factor(study_id),
    group = factor(randomization_group, levels = c(0,1), labels = c("BMRA","BMRA-CLO")),
    sexo  = factor(sex, levels = c(1,0), labels = c("M","F")),
    idade = age, peso = weight, altura = height,
    imc   = if (tem_col("bmi")) bmi else weight/(height^2),
    asa   = factor(asa_ps, levels = c(1,2), labels = c("I","II")),

    HAS              = get_bin_factor("HAS"),
    DM               = get_bin_factor(c("DM","Diabetes")),
    Asma             = get_bin_factor("Asma"),
    Dislipidemia     = get_bin_factor(c("Dislipidemia","DLP")),
    Hipotireoidismo  = get_bin_factor("Hipotireoidismo"),
    Hipertireoidismo = get_bin_factor("Hipertireoidismo"),
    IRC              = get_bin_factor(c("Insuficiencia Renal Cronica","Insuficiência Renal","Insuficiencia Renal")),
    Epilepsia        = get_bin_factor("Epilepsia"),
    Ansiedade        = get_bin_factor("Ansiedade"),
    Depressao        = get_bin_factor(c("Depressão","Depressao")),
    Anemia           = get_bin_factor("Anemia"),
    ArtriteReumatoide = get_bin_factor(c("Artrite Reumatóide","Artrite Reumatoide")),
    Obesidade        = get_bin_factor("Obesidade"),

    fentanyl_per_kg = fentanyl / weight,
    qor_srpa = soma_qor(""),
    qor_24h  = soma_qor("_24h"),
    qor_48h  = soma_qor("_48h")
  )

Reconciliação dos totais de QoR-15: linhas em que o total armazenado no banco diverge da soma dos 15 itens (referência adotada na análise).

recon <- tibble::tibble(
  study_id        = dados$study_id,
  SRPA_itens      = dados$qor_srpa,
  SRPA_armazenado = if (tem_col("qor15_24h_total")) dados$qor15_24h_total else NA_real_,
  h24_itens       = dados$qor_24h,
  h24_armazenado  = if (tem_col("QoR-15 24h")) dados[["QoR-15 24h"]] else NA_real_,
  h48_itens       = dados$qor_48h,
  h48_armazenado  = if (tem_col("QoR-48h")) dados[["QoR-48h"]] else NA_real_
) %>%
  filter(SRPA_itens != SRPA_armazenado |
         h24_itens  != h24_armazenado  |
         h48_itens  != h48_armazenado)

if (nrow(recon))
  knitr::kable(recon, caption = "Divergências entre total armazenado e soma dos 15 itens")
Table 4.1: Divergências entre total armazenado e soma dos 15 itens
study_id SRPA_itens SRPA_armazenado h24_itens h24_armazenado h48_itens h48_armazenado
29 144 144 148 150 150 150
30 140 139 148 148 149 149
36 125 115 133 123 145 145

Estatística descritiva básica:

dados %>%
  dplyr::select(any_of(c(
    "group","sexo","idade","peso","altura","imc","asa",
    "HAS","DM","Asma","Dislipidemia","Hipotireoidismo","Hipertireoidismo",
    "IRC","Epilepsia","Ansiedade","Depressao","Anemia","ArtriteReumatoide","Obesidade",
    "qor_srpa","qor_24h","qor_48h"
  ))) %>%
  summary()
##       group    sexo       idade            peso            altura     
##  BMRA    :19   M:20   Min.   :20.00   Min.   : 47.50   Min.   :1.470  
##  BMRA-CLO:20   F:19   1st Qu.:36.00   1st Qu.: 68.30   1st Qu.:1.610  
##                       Median :44.00   Median : 74.60   Median :1.660  
##                       Mean   :44.23   Mean   : 75.42   Mean   :1.667  
##                       3rd Qu.:51.00   3rd Qu.: 81.20   3rd Qu.:1.730  
##                       Max.   :64.00   Max.   :114.00   Max.   :1.830  
##       imc        asa      HAS       DM      Asma    Dislipidemia
##  Min.   :18.60   I :10   Nao:25   Nao:36   Nao:38   Nao:38      
##  1st Qu.:25.45   II:29   Sim:14   Sim: 3   Sim: 1   Sim: 1      
##  Median :26.90                                                  
##  Mean   :27.02                                                  
##  3rd Qu.:29.35                                                  
##  Max.   :35.60                                                  
##  Hipotireoidismo Hipertireoidismo  IRC     Epilepsia Ansiedade Depressao
##  Nao:39          Nao:38           Nao:39   Nao:39    Nao:37    Nao:37   
##  Sim: 0          Sim: 1           Sim: 0   Sim: 0    Sim: 2    Sim: 2   
##                                                                         
##                                                                         
##                                                                         
##                                                                         
##  Anemia   ArtriteReumatoide Obesidade    qor_srpa        qor_24h     
##  Nao:39   Nao:39            Nao:37    Min.   :100.0   Min.   :124.0  
##  Sim: 0   Sim: 0            Sim: 2    1st Qu.:128.0   1st Qu.:141.0  
##                                       Median :135.0   Median :145.0  
##                                       Mean   :133.6   Mean   :143.7  
##                                       3rd Qu.:140.5   3rd Qu.:148.5  
##                                       Max.   :150.0   Max.   :150.0  
##     qor_48h     
##  Min.   :129.0  
##  1st Qu.:146.0  
##  Median :149.0  
##  Mean   :147.3  
##  3rd Qu.:150.0  
##  Max.   :150.0

5 Tabela 1

Características basais, comorbidades, valor-p e teste aplicado:

N    <- table(dados$group)
col1 <- sprintf("BMRA (n=%d)", N["BMRA"])
col2 <- sprintf("BMRA-CLO (n=%d)", N["BMRA-CLO"])
addrow <- function(rot, v1, v2, p)
  tibble(Variável = rot, !!col1 := v1, !!col2 := v2, `Valor-p` = p)

linhas <- list()

cont_map <- c(idade="Idade (anos)", peso="Peso (kg)", altura="Altura (m)", imc="IMC (kg/m²)")
for (v in names(cont_map)) {
  tt <- get_test_cont(dados[[v]], dados$group)
  linhas[[v]] <- addrow(cont_map[[v]],
    fmt_mean_sd(dados[[v]][dados$group=="BMRA"]),
    fmt_mean_sd(dados[[v]][dados$group=="BMRA-CLO"]),
    fmt_p_sym(tt$p, tt$sym))
}

tt <- get_test_cat(dados$sexo, dados$group)
for (lv in levels(dados$sexo)) {
  n1 <- sum(dados$sexo==lv & dados$group=="BMRA", na.rm=TRUE)
  n2 <- sum(dados$sexo==lv & dados$group=="BMRA-CLO", na.rm=TRUE)
  linhas[[paste0("sexo_",lv)]] <- addrow(paste0("Sexo — ", lv),
    fmt_n_pct(n1, N["BMRA"]), fmt_n_pct(n2, N["BMRA-CLO"]),
    if (lv==levels(dados$sexo)[1]) fmt_p_sym(tt$p, tt$sym) else "")
}

tt <- get_test_cat(dados$asa, dados$group)
for (lv in levels(dados$asa)) {
  n1 <- sum(dados$asa==lv & dados$group=="BMRA", na.rm=TRUE)
  n2 <- sum(dados$asa==lv & dados$group=="BMRA-CLO", na.rm=TRUE)
  linhas[[paste0("asa_",lv)]] <- addrow(paste0("ASA — ", lv),
    fmt_n_pct(n1, N["BMRA"]), fmt_n_pct(n2, N["BMRA-CLO"]),
    if (lv==levels(dados$asa)[1]) fmt_p_sym(tt$p, tt$sym) else "")
}

comorb_map <- c(HAS="Hipertensão arterial", DM="Diabetes mellitus", Asma="Asma",
                Dislipidemia="Dislipidemia", Hipotireoidismo="Hipotireoidismo",
                Hipertireoidismo="Hipertireoidismo", IRC="Insuficiência renal crônica",
                Epilepsia="Epilepsia", Ansiedade="Ansiedade", Depressao="Depressão",
                Anemia="Anemia", ArtriteReumatoide="Artrite reumatoide", Obesidade="Obesidade")
for (v in names(comorb_map)) {
  if (sum(dados[[v]]=="Sim", na.rm=TRUE) == 0) next   # pula comorbidade ausente
  tt <- get_test_cat(dados[[v]], dados$group)
  n1 <- sum(dados[[v]]=="Sim" & dados$group=="BMRA", na.rm=TRUE)
  n2 <- sum(dados[[v]]=="Sim" & dados$group=="BMRA-CLO", na.rm=TRUE)
  linhas[[v]] <- addrow(comorb_map[[v]],
    fmt_n_pct(n1, N["BMRA"]), fmt_n_pct(n2, N["BMRA-CLO"]), fmt_p_sym(tt$p, tt$sym))
}

Tabela1 <- bind_rows(linhas)

Tabela1 %>%
  kbl(align = c("l","c","c","c"), escape = FALSE,
      caption = "<b style='color:#2C3E50'>Tabela 1 — Características basais e comorbidades</b>") %>%
  kable_styling(bootstrap_options = c("hover","condensed","striped"),
                full_width = FALSE, font_size = 14, position = "center") %>%
  row_spec(0, bold = TRUE, color = "white", background = "#2C3E50") %>%
  column_spec(1, bold = TRUE, color = "#2C3E50", width = "20em") %>%
  footnote(general = paste0(
      "Contínuas: média ± DP; categóricas: n (%).<br>",
      "<sup>*</sup> Qui-quadrado; <sup>&sect;</sup> Exato de Fisher; ",
      "<sup>&dagger;</sup> t de Welch; <sup>&Dagger;</sup> Mann–Whitney.<br>",
      "<b>Negrito</b> indica significância estatística (p &lt; 0,05)."),
    general_title = "Legenda: ", footnote_as_chunk = TRUE, escape = FALSE)
Table 5.1: Tabela 1 — Características basais e comorbidades
Variável BMRA (n=19) BMRA-CLO (n=20) Valor-p
Idade (anos) 44,95 ± 10,46 43,55 ± 12,24 0,703
Peso (kg) 77,47 ± 15,02 73,48 ± 12,21 0,371
Altura (m) 1,67 ± 0,09 1,66 ± 0,08 0,830
IMC (kg/m²) 27,61 ± 3,78 26,45 ± 3,47 0,329
Sexo — M 9 (47,4%) 11 (55,0%) 0,634*
Sexo — F 10 (52,6%) 9 (45,0%)
ASA — I 4 (21,1%) 6 (30,0%) 0,716§
ASA — II 15 (78,9%) 14 (70,0%)
Hipertensão arterial 9 (47,4%) 5 (25,0%) 0,146*
Diabetes mellitus 1 (5,3%) 2 (10,0%) 1,000§
Asma 1 (5,3%) 0 (0,0%) 0,487§
Dislipidemia 1 (5,3%) 0 (0,0%) 0,487§
Hipertireoidismo 0 (0,0%) 1 (5,0%) 1,000§
Ansiedade 0 (0,0%) 2 (10,0%) 0,487§
Depressão 0 (0,0%) 2 (10,0%) 0,487§
Obesidade 2 (10,5%) 0 (0,0%) 0,231§
Legenda: Contínuas: média ± DP; categóricas: n (%).
* Qui-quadrado; § Exato de Fisher; t de Welch; Mann–Whitney.
Negrito indica significância estatística (p < 0,05).

6 Visualizações

6.1 Perfil etário da população estudada

media_idade   <- mean(dados$idade,   na.rm = TRUE)
mediana_idade <- median(dados$idade, na.rm = TRUE)
dp_idade      <- sd(dados$idade,     na.rm = TRUE)
bw_idade      <- diff(range(dados$idade, na.rm = TRUE)) / 20

ggplot(dados, aes(x = idade)) +
  geom_histogram(aes(fill = after_stat(count)),
                 binwidth = bw_idade, boundary = 0, closed = "left", alpha = 0.95) +
  # densidade reescalada para contagem (× binwidth) para casar com as barras
  stat_density(aes(y = after_stat(count) * bw_idade),
               geom = "line", linewidth = 1.1, na.rm = TRUE) +
  geom_vline(xintercept = media_idade,   linewidth = 0.8) +
  geom_vline(xintercept = mediana_idade, linetype = "dashed", linewidth = 0.8) +
  geom_rug(sides = "b", alpha = 0.25, linewidth = 0.3) +
  scale_fill_gradient(low = "#E9EDF5", high = "#4FA2DA") +
  labs(title = "Distribuição da idade",
       subtitle = sprintf("Média = %.1f ± %.1f | Mediana = %.1f",
                          media_idade, dp_idade, mediana_idade),
       x = "Idade (anos)", y = "Frequência") +
  guides(fill = "none")

A distribuição etária dos participantes demonstra uma população predominantemente de meia-idade, típica para cirurgias de hérnia umbilical em regime ambulatorial. A sobreposição da curva de densidade indica uma distribuição relativamente simétrica, sugerindo que a amostra é representativa e não apresenta desvios extremos de idade que pudessem enviesar a farmacocinética dos anestésicos.

6.2 Evolução da dor pós-operatória (repouso vs. movimento)

colmap <- c("NRS RPA r"="SRPA_Repouso","NRS RPA m"="SRPA_Movimento",
            "NRS 24h r"="24h_Repouso", "NRS 24h m"="24h_Movimento",
            "NRS 48h r"="48h_Repouso", "NRS 48h m"="48h_Movimento")
present <- intersect(names(colmap), names(dados))

df_long <- dados %>%
  select(group, all_of(present)) %>%
  rename(!!!setNames(present, colmap[present])) %>%
  pivot_longer(-group, names_to = "key", values_to = "nrs") %>%
  separate(key, into = c("momento","cond"), sep = "_") %>%
  mutate(nrs = as.numeric(nrs),
         momento = factor(momento, levels = c("SRPA","24h","48h")),
         cond    = factor(cond,    levels = c("Repouso","Movimento"))) %>%
  filter(!is.na(nrs))

painel_test <- function(d) {
  ct <- table(d$group)
  if (length(ct) < 2 || any(ct < 2)) return(NA_real_)
  norm <- tapply(d$nrs, d$group, function(v) if (length(v) >= 3) shapiro.test(v)$p.value >= .05 else FALSE)
  if (all(unlist(norm))) t.test(nrs ~ group, d)$p.value
  else suppressWarnings(wilcox.test(nrs ~ group, d, exact = FALSE)$p.value)
}

tests <- df_long %>%
  group_by(momento, cond) %>%
  group_modify(~ tibble(p = painel_test(.x))) %>%
  ungroup() %>%
  mutate(p_label = ifelse(is.na(p), "",
                          ifelse(p < .001, "p < 0,001",
                                 paste0("p = ", nv(p, 3)))))
y_pos  <- df_long %>% group_by(momento, cond) %>%
  summarise(y_p = min(10, max(nrs) + 0.6), .groups = "drop")
tests  <- left_join(tests, y_pos, by = c("momento","cond"))

pd <- position_dodge(width = 0.8)
ggplot(df_long, aes(momento, nrs, fill = group)) +
  geom_boxplot(width = 0.65, position = pd, outlier.shape = 8, outlier.size = 2, alpha = 0.92) +
  stat_summary(aes(group = group), fun = mean, geom = "point",
               shape = 18, size = 3, color = "black", position = pd) +
  stat_summary(aes(label = sprintf("%.2f", after_stat(y)), group = group),
               fun = mean, geom = "text", fontface = "bold", vjust = -0.6, size = 3.2, position = pd) +
  geom_text(data = tests, aes(momento, y_p, label = p_label),
            fontface = "bold", size = 3.2, inherit.aes = FALSE) +
  facet_wrap(~ cond, nrow = 1) +
  scale_fill_manual(values = pal_grupo, name = "Grupo") +
  labs(title = "EVN de dor (0–10) em repouso e movimento — SRPA, 24h e 48h",
       x = "Tempo de avaliação", y = "EVN (0–10)") +
  coord_cartesian(ylim = c(0, 10)) +
  theme(legend.position = "right")

6.3 Trajetória da qualidade de recuperação (QoR-15)

dados_long <- dados %>%
  transmute(group, SRPA = qor_srpa, `24h` = qor_24h, `48h` = qor_48h) %>%
  pivot_longer(c("SRPA","24h","48h"), names_to = "tempo", values_to = "qor15") %>%
  filter(!is.na(qor15)) %>%
  mutate(tempo = factor(tempo, levels = c("SRPA","24h","48h")))

sw <- dados_long %>% group_by(tempo, group) %>% shapiro_test(qor15)

testes <- dados_long %>%
  group_split(tempo) %>%
  lapply(function(d) {
    t_atual <- as.character(unique(d$tempo))
    sw_t    <- sw %>% filter(tempo == t_atual)
    n_min   <- min(table(d$group))
    if (any(sw_t$p < .05) || n_min < 8) {
      tt <- wilcox_test(d, qor15 ~ group); tt$test_used <- "Wilcoxon"
    } else {
      tt <- t_test(d, qor15 ~ group, var.equal = FALSE); tt$test_used <- "Welch"
    }
    tt$tempo <- t_atual; tt
  }) %>% bind_rows()

tests_lab <- testes %>%
  mutate(p_label = ifelse(p < .001, "p < 0,001", paste0("p = ", nv(p, 3))))
y_pos <- dados_long %>% group_by(tempo) %>%
  summarise(y_p = max(qor15, na.rm = TRUE) + 4, .groups = "drop")
tests_lab <- left_join(tests_lab, y_pos, by = "tempo") %>%
  mutate(tempo = factor(tempo, levels = c("SRPA","24h","48h")))

means_df <- dados_long %>% group_by(tempo, group) %>%
  summarise(y = mean(qor15, na.rm = TRUE), .groups = "drop")

pd <- position_dodge(width = 0.8)
ggplot(dados_long, aes(tempo, qor15, fill = group)) +
  geom_boxplot(width = 0.65, position = pd, outlier.shape = 8, outlier.size = 2, alpha = 0.90) +
  geom_point(data = means_df, aes(tempo, y, group = group),
             position = pd, shape = 18, size = 3, color = "black") +
  shadowtext::geom_shadowtext(
    data = means_df, aes(tempo, y, label = sprintf("%.1f", y), group = group),
    position = pd, fontface = "bold", size = 3.4, vjust = -0.6,
    colour = "black", bg.colour = "white", bg.r = 0.12) +
  geom_text(data = tests_lab, aes(tempo, y_p, label = p_label),
            fontface = "bold", size = 3.6, inherit.aes = FALSE) +
  scale_fill_manual(values = pal_grupo, name = "Grupo") +
  labs(title = "Qualidade de recuperação (QoR-15)", x = "Tempo de avaliação", y = "QoR-15") +
  coord_cartesian(clip = "off") +
  theme(legend.position = "right", plot.margin = margin(10, 20, 10, 10))

6.4 Relevância clínica das diferenças no QoR-15

A área sombreada em cinza representa a Diferença Mínima Clinicamente Importante (MCID) de ±8 pontos. O gráfico mostra que, em todos os momentos (SRPA, 24h e 48h), a diferença entre os grupos permanece dentro dessa faixa e os intervalos de confiança de 95% incluem zero, indicando ausência de significância estatística e de relevância clínica.

dl <- dados %>%
  transmute(id, group, SRPA = qor_srpa, `24h` = qor_24h, `48h` = qor_48h) %>%
  pivot_longer(c("SRPA","24h","48h"), names_to = "tempo", values_to = "qor15") %>%
  filter(!is.na(qor15), !is.na(group)) %>%
  mutate(tempo = factor(tempo, levels = c("SRPA","24h","48h")))

fit    <- lmer(qor15 ~ group * tempo + (1 | id), data = dl)
emm    <- emmeans(fit, ~ group | tempo)
emm_df <- as.data.frame(emm)

# pairwise devolve (BMRA − BMRA-CLO); inverter para (CLO − BMRA)
contr <- as.data.frame(confint(contrast(emm, method = "pairwise")))
contr$estimate <- -contr$estimate
tmp <- contr$lower.CL; contr$lower.CL <- -contr$upper.CL; contr$upper.CL <- -tmp

nv1  <- function(x) formatC(x, digits = 1, format = "f", decimal.mark = ",")
sgn  <- function(x) ifelse(x >= 0, paste0("+", nv1(x)), paste0("−", nv1(abs(x))))
delta_labs <- contr %>%
  transmute(tempo, delta_lab = sprintf("Δ=%s [%s; %s]", sgn(estimate), nv1(lower.CL), nv1(upper.CL)))

mcid_w <- 0.46
base_mcid <- emm_df %>% filter(group == "BMRA") %>%
  mutate(xn = as.numeric(tempo), xmin = xn - mcid_w, xmax = xn + mcid_w,
         ymin = emmean - 8, ymax = emmean + 8)

y_top <- emm_df %>% group_by(tempo) %>%
  summarise(y = max(upper.CL, na.rm = TRUE) + 3, .groups = "drop") %>%
  left_join(delta_labs, by = "tempo")
y_lo <- max(0, floor(min(c(emm_df$lower.CL, base_mcid$ymin), na.rm = TRUE) - 3))
y_hi <- ceiling(max(c(emm_df$upper.CL, base_mcid$ymax, y_top$y), na.rm = TRUE) + 2)

ggplot(emm_df, aes(tempo, emmean, color = group, group = group)) +
  geom_rect(data = base_mcid, aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax),
            inherit.aes = FALSE, fill = "grey60", alpha = 0.14) +
  geom_line(linewidth = 1) + geom_point(size = 3) +
  geom_errorbar(aes(ymin = lower.CL, ymax = upper.CL), width = .08, linewidth = 0.8) +
  geom_text(data = y_top, aes(tempo, y, label = delta_lab),
            inherit.aes = FALSE, size = 4, fontface = "bold") +
  scale_color_manual(values = pal_grupo, name = "Grupo") +
  labs(title = "QoR-15 — médias marginais estimadas (EMM), IC95% e faixa de MCID (±8)",
       x = "Tempo de avaliação", y = "QoR-15 (EMM)") +
  scale_y_continuous(limits = c(y_lo, y_hi), expand = expansion(mult = c(.02, .08))) +
  theme(legend.position = "right")

7 Tabela 2 — Desfechos

n1 <- sum(dados$group == "BMRA"); n2 <- sum(dados$group == "BMRA-CLO")
cB <- sprintf("BMRA (n=%d)", n1); cC <- sprintf("BMRA-CLO (n=%d)", n2)

get_row <- function(rot, col, tipo = c("auto","np")) {
  tipo <- match.arg(tipo)
  if (!col %in% names(dados)) return(NULL)
  x <- dados[[col]]; g <- dados$group
  if (tipo == "np") {
    tt <- list(p = suppressWarnings(wilcox.test(x ~ g, exact = FALSE)$p.value), sym = "&Dagger;")
    v1 <- fmt_non_param(x[g == "BMRA"]); v2 <- fmt_non_param(x[g == "BMRA-CLO"])
  } else {
    tt <- get_test_cont(x, g)
    v1 <- fmt_mean_sd(x[g == "BMRA"]);   v2 <- fmt_mean_sd(x[g == "BMRA-CLO"])
  }
  tibble(Variável = rot, !!cB := v1, !!cC := v2, `Valor-p` = fmt_p_sym(tt$p, tt$sym))
}

intra <- list(
  get_row("Propofol (mg)",            "propofol",            "np"),
  get_row("Fentanil (µg)",            "fentanyl",            "auto"),
  get_row("Fentanil (µg/kg)",         "fentanyl_per_kg",     "auto"),
  get_row("Midazolam (mg)",           "midazolam",           "auto"),
  get_row("Tempo de anestesia (min)", "anesthesia_time_min", "auto"),
  get_row("Tempo de cirurgia (min)",  "surgery_time_min",    "auto"))
hemo <- list(
  get_row("PAS inicial (mmHg)", "sys_bp_start",  "auto"),
  get_row("PAD inicial (mmHg)", "dyas_bp_start", "auto"),
  get_row("PAM inicial (mmHg)", "mean_bp_start", "auto"),
  get_row("FC inicial (bpm)",   "hr_start",      "auto"),
  get_row("PAS final (mmHg)",   "sys_bp_end",    "auto"),
  get_row("PAD final (mmHg)",   "dyas_bp_end",   "auto"),
  get_row("PAM final (mmHg)",   "mean_bp_end",   "auto"),
  get_row("FC final (bpm)",     "hr_end",        "auto"))
pos <- list(
  get_row("RASS (SRPA)",              "rass_rpa", "np"),
  get_row("Tempo até 1ª analgesia (h)","Primeira", "auto"),
  get_row("QoR-15 (SRPA)",            "qor_srpa", "np"),
  get_row("QoR-15 (24h)",             "qor_24h",  "np"),
  get_row("QoR-15 (48h)",             "qor_48h",  "np"))
dor <- list(
  get_row("EVN repouso (SRPA)",   "NRS RPA r", "np"),
  get_row("EVN movimento (SRPA)", "NRS RPA m", "np"),
  get_row("EVN repouso (24h)",    "NRS 24h r", "np"),
  get_row("EVN movimento (24h)",  "NRS 24h m", "np"),
  get_row("EVN repouso (48h)",    "NRS 48h r", "np"),
  get_row("EVN movimento (48h)",  "NRS 48h m", "np"))

T2 <- bind_rows(c(intra, hemo, pos, dor))

T2 %>%
  kbl(align = c("l","c","c","c"), escape = FALSE,
      caption = "<b style='color:#2C3E50'>Tabela 2 — Desfechos do estudo</b>") %>%
  kable_styling(bootstrap_options = c("striped","hover","condensed"),
                full_width = FALSE, font_size = 13) %>%
  row_spec(0, bold = TRUE, color = "white", background = "#2C3E50") %>%
  column_spec(1, bold = TRUE, color = "#2C3E50", width = "18em") %>%
  pack_rows("Dados intraoperatórios",            1,  6,  label_row_css = "background:#ecf0f1;color:#2C3E50;font-weight:bold;") %>%
  pack_rows("Dados hemodinâmicos",               7,  14, label_row_css = "background:#ecf0f1;color:#2C3E50;font-weight:bold;") %>%
  pack_rows("Pós-operatório e recuperação",      15, 19, label_row_css = "background:#ecf0f1;color:#2C3E50;font-weight:bold;") %>%
  pack_rows("Escala visual numérica de dor (0–10)", 20, 25, label_row_css = "background:#ecf0f1;color:#2C3E50;font-weight:bold;") %>%
  footnote(general = paste0(
      "Dados como <b>média ± DP</b> ou <b>mediana (P25–P75) [mín–máx]</b>.<br>",
      "<sup>&dagger;</sup> t de Welch; <sup>&Dagger;</sup> Mann–Whitney.<br>",
      "<b>Negrito</b> indica significância estatística (p &lt; 0,05)."),
    general_title = " ", footnote_as_chunk = TRUE, escape = FALSE)
Table 7.1: Tabela 2 — Desfechos do estudo
Variável BMRA (n=19) BMRA-CLO (n=20) Valor-p
Dados intraoperatórios
Propofol (mg) 0 (0–0) [0–60] 0 (0–0) [0–30] 0,523
Fentanil (µg) 109,74 ± 34,01 61,00 ± 20,49 <0,001
Fentanil (µg/kg) 1,44 ± 0,44 0,84 ± 0,26 <0,001
Midazolam (mg) 6,00 ± 2,24 5,85 ± 2,28 0,837
Tempo de anestesia (min) 72,53 ± 18,41 69,40 ± 21,99 0,448
Tempo de cirurgia (min) 50,47 ± 15,85 47,75 ± 20,05 0,391
Dados hemodinâmicos
PAS inicial (mmHg) 138,26 ± 18,93 136,85 ± 15,80 0,802
PAD inicial (mmHg) 87,63 ± 10,40 85,25 ± 15,53 0,910
PAM inicial (mmHg) 104,51 ± 12,67 102,45 ± 14,37 0,637
FC inicial (bpm) 72,42 ± 12,79 79,05 ± 19,91 0,391
PAS final (mmHg) 115,00 ± 19,40 109,30 ± 15,19 0,316
PAD final (mmHg) 77,47 ± 14,83 70,70 ± 12,15 0,129
PAM final (mmHg) 89,98 ± 15,94 83,57 ± 12,91 0,177
FC final (bpm) 68,53 ± 14,22 67,50 ± 13,05 0,833
Pós-operatório e recuperação
RASS (SRPA) -1 (-1–-1) [-2–0] -1 (-1–0) [-3–0] 0,276
Tempo até 1ª analgesia (h) 8,47 ± 1,77 9,39 ± 1,80 0,118
QoR-15 (SRPA) 132 (128–142) [100–150] 137 (131–139) [106–150] 0,415
QoR-15 (24h) 144 (138–147) [124–150] 146 (143–149) [135–150] 0,185
QoR-15 (48h) 146 (144–150) [129–150] 149 (148–150) [146–150] 0,008
Escala visual numérica de dor (0–10)
EVN repouso (SRPA) 0 (0–0) [0–2] 0 (0–0) [0–1] 0,936
EVN movimento (SRPA) 0 (0–2) [0–5] 0 (0–1) [0–4] 0,675
EVN repouso (24h) 0 (0–3) [0–5] 1 (0–2) [0–4] 0,756
EVN movimento (24h) 3 (3–4) [0–7] 3 (3–4) [0–6] 0,896
EVN repouso (48h) 0 (0–2) [0–3] 0 (0–0) [0–2] 0,023
EVN movimento (48h) 2 (1–3) [0–4] 1 (1–2) [0–4] 0,231
Dados como média ± DP ou mediana (P25–P75) [mín–máx].
t de Welch; Mann–Whitney.
Negrito indica significância estatística (p < 0,05).

8 ANOVA de medidas repetidas

# QoR-15 — ANOVA mista 2×3 (tipo III, η² parcial, correção GG quando indicada)
afex::afex_options(type = 3)

dq <- dados %>%
  transmute(id, group, SRPA = qor_srpa, `24h` = qor_24h, `48h` = qor_48h) %>%
  pivot_longer(c("SRPA","24h","48h"), names_to = "tempo", values_to = "qor15") %>%
  filter(!is.na(qor15)) %>%
  mutate(tempo = factor(tempo, levels = c("SRPA","24h","48h")))

fit_qor <- afex::aov_car(qor15 ~ group * tempo + Error(id/tempo),
                         data = dq, anova_table = list(es = "pes"))
fit_qor
## Anova Table (Type 3 tests)
## 
## Response: qor15
##        Effect          df    MSE         F  pes p.value
## 1       group       1, 37 107.27      2.71 .068    .108
## 2       tempo 1.16, 42.76  54.14 63.24 *** .631   <.001
## 3 group:tempo 1.16, 42.76  54.14      0.05 .001    .855
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '+' 0.1 ' ' 1
## 
## Sphericity correction method: GG
emmeans(fit_qor, ~ group | tempo)
## tempo = SRPA:
##  group    emmean    SE df lower.CL upper.CL
##  BMRA        132 2.520 37      127      137
##  BMRA-CLO    135 2.460 37      130      140
## 
## tempo = X24h:
##  group    emmean    SE df lower.CL upper.CL
##  BMRA        142 1.380 37      139      145
##  BMRA-CLO    145 1.350 37      143      148
## 
## tempo = X48h:
##  group    emmean    SE df lower.CL upper.CL
##  BMRA        146 0.815 37      144      147
##  BMRA-CLO    149 0.794 37      147      150
## 
## Confidence level used: 0.95
contrast(emmeans(fit_qor, ~ group | tempo), method = "pairwise", adjust = "holm")
## tempo = SRPA:
##  contrast          estimate   SE df t.ratio p.value
##  BMRA - (BMRA-CLO)    -2.74 3.52 37  -0.778  0.4414
## 
## tempo = X24h:
##  contrast          estimate   SE df t.ratio p.value
##  BMRA - (BMRA-CLO)    -3.56 1.93 37  -1.844  0.0733
## 
## tempo = X48h:
##  contrast          estimate   SE df t.ratio p.value
##  BMRA - (BMRA-CLO)    -3.17 1.14 37  -2.783  0.0084
# EVN — ANOVA mista 2×3×2 (group × tempo × cond)
de <- dados %>%
  select(id, group, dplyr::starts_with("NRS ")) %>%
  pivot_longer(-c(id, group), names_to = "key", values_to = "nrs") %>%
  tidyr::extract(key, into = c("tempo","cond"), regex = "^NRS (RPA|24h|48h) (r|m)$") %>%
  mutate(tempo = factor(ifelse(tempo == "RPA","SRPA",tempo), levels = c("SRPA","24h","48h")),
         cond  = factor(ifelse(cond == "r","Repouso","Movimento"), levels = c("Repouso","Movimento"))) %>%
  filter(!is.na(nrs))

fit_evn <- afex::aov_car(nrs ~ group * tempo * cond + Error(id/(tempo*cond)),
                         data = de, anova_table = list(es = "pes"))
fit_evn
## Anova Table (Type 3 tests)
## 
## Response: nrs
##             Effect          df  MSE          F  pes p.value
## 1            group       1, 37 3.67       0.96 .025    .333
## 2            tempo 1.59, 58.86 1.96  48.85 *** .569   <.001
## 3      group:tempo 1.59, 58.86 1.96       1.15 .030    .313
## 4             cond       1, 37 0.82 116.39 *** .759   <.001
## 5       group:cond       1, 37 0.82       0.12 .003    .729
## 6       tempo:cond 1.81, 66.85 0.59  16.60 *** .310   <.001
## 7 group:tempo:cond 1.81, 66.85 0.59       0.04 .001    .948
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '+' 0.1 ' ' 1
## 
## Sphericity correction method: GG

9 Modelos de regressão linear

Três modelos complementam as comparações simples: (1) ANCOVA para o desfecho primário (fentanil µg/kg), (2) regressão linear múltipla para o QoR-15 em 48h ajustado pelo basal, e (3) modelo linear misto para a trajetória do EVN em movimento. Em n=39, limitamos a no máximo 5 covariáveis por modelo (≈ 10 observações por preditor).

9.1 ANCOVA — desfecho primário (fentanil µg/kg)

fentanyl_per_kg ~ group + idade + imc + sexo + asa — fornece a diferença média ajustada entre grupos (CLO − BMRA) com IC 95% e p-valor, controlando desbalanços basais.

fit_ancova <- lm(fentanyl_per_kg ~ group + idade + imc + sexo + asa, data = dados)

# Tabela de coeficientes
coef_tab <- parameters::model_parameters(fit_ancova, ci = 0.95) %>%
  as.data.frame() %>%
  transmute(
    Termo       = Parameter,
    Coeficiente = nv(Coefficient, 3),
    `IC 95%`    = sprintf("[%s; %s]", nv(CI_low, 3), nv(CI_high, 3)),
    `Valor-p`   = ifelse(p < 0.001, "&lt;0,001", nv(p, 3))
  )
knitr::kable(coef_tab, align = c("l","c","c","c"),
             caption = "ANCOVA — coeficientes do modelo (fentanil µg/kg)")
(#tab:ancova_fent)ANCOVA — coeficientes do modelo (fentanil µg/kg)
Termo Coeficiente IC 95% Valor-p
(Intercept) 1,267 [0,070; 2,464] 0,039
groupBMRA-CLO -0,589 [-0,829; -0,349] <0,001
idade 0,001 [-0,010; 0,012] 0,865
imc 0,004 [-0,032; 0,039] 0,837
sexoF 0,198 [-0,065; 0,460] 0,135
asaII -0,094 [-0,379; 0,191] 0,507
# Diferença média ajustada (CLO − BMRA)
emm_anc       <- emmeans(fit_ancova, ~ group)
contr_anc_obj <- contrast(emm_anc, method = "pairwise")
diff_anc      <- as.data.frame(summary(contr_anc_obj, infer = c(TRUE, TRUE)))
diff_anc$estimate <- -diff_anc$estimate
tmp <- diff_anc$lower.CL; diff_anc$lower.CL <- -diff_anc$upper.CL; diff_anc$upper.CL <- -tmp

ajust <- tibble::tibble(
  Contraste                         = "BMRA-CLO − BMRA",
  `Diferença ajustada (µg/kg)`      = nv(diff_anc$estimate, 3),
  `IC 95%`                          = sprintf("[%s; %s]", nv(diff_anc$lower.CL, 3), nv(diff_anc$upper.CL, 3)),
  `Valor-p`                         = ifelse(diff_anc$p.value < 0.001, "&lt;0,001", nv(diff_anc$p.value, 3))
)
knitr::kable(ajust, align = c("l","c","c","c"),
             caption = "Diferença média ajustada por ANCOVA (com IC 95% e p)")
(#tab:ancova_fent)Diferença média ajustada por ANCOVA (com IC 95% e p)
Contraste Diferença ajustada (µg/kg) IC 95% Valor-p
BMRA-CLO − BMRA -0,589 [-0,829; -0,349] <0,001
# η² parcial (tamanho de efeito)
effectsize::eta_squared(fit_ancova, partial = TRUE)

10 Effect Size for ANOVA (Type I)

10.1 Parameter | Eta2 (partial) | 95% CI

group | 0.46 | [0.24, 1.00] idade | 8.59e-03 | [0.00, 1.00] imc | 5.04e-03 | [0.00, 1.00] sexo | 0.08 | [0.00, 1.00] asa | 0.01 | [0.00, 1.00]

  • One-sided CIs: upper bound fixed at [1.00].
# Pressupostos
shapiro.test(residuals(fit_ancova))   # normalidade dos resíduos
Shapiro-Wilk normality test

data: residuals(fit_ancova) W = 0.96615, p-value = 0.2841

car::ncvTest(fit_ancova)              # homocedasticidade (Breusch–Pagan)

Non-constant Variance Score Test Variance formula: ~ fitted.values Chisquare = 1.573386, Df = 1, p = 0.20972

# Forest plot dos coeficientes
fp <- parameters::model_parameters(fit_ancova, ci = 0.95) %>%
  as.data.frame() %>%
  filter(Parameter != "(Intercept)") %>%
  mutate(Parameter = factor(Parameter, levels = rev(Parameter)))

ggplot(fp, aes(Coefficient, Parameter)) +
  geom_vline(xintercept = 0, linetype = "dashed", color = "#7f8c8d") +
  geom_pointrange(aes(xmin = CI_low, xmax = CI_high), size = 0.6, color = cor_controle) +
  labs(title = "ANCOVA — coeficientes (IC 95%) para fentanil (µg/kg)",
       x = "Coeficiente", y = NULL)

10.2 Regressão linear múltipla — QoR-15 em 48h ajustado pelo basal

qor_48h ~ group + qor_srpa + idade + sexo + imc — o ajuste por qor_srpa (basal) aumenta a precisão da estimativa do efeito do grupo no momento clinicamente mais relevante.

fit_qor48 <- lm(qor_48h ~ group + qor_srpa + idade + sexo + imc, data = dados)

coef_tab2 <- parameters::model_parameters(fit_qor48, ci = 0.95) %>%
  as.data.frame() %>%
  transmute(
    Termo       = Parameter,
    Coeficiente = nv(Coefficient, 2),
    `IC 95%`    = sprintf("[%s; %s]", nv(CI_low, 2), nv(CI_high, 2)),
    `Valor-p`   = ifelse(p < 0.001, "&lt;0,001", nv(p, 3))
  )
knitr::kable(coef_tab2, align = c("l","c","c","c"),
             caption = "Regressão linear múltipla — QoR-15 em 48h")
(#tab:rlm_qor48)Regressão linear múltipla — QoR-15 em 48h
Termo Coeficiente IC 95% Valor-p
(Intercept) 129,16 [109,97; 148,35] <0,001
groupBMRA-CLO 2,79 [0,47; 5,12] 0,020
qor_srpa 0,13 [0,02; 0,25] 0,022
idade -0,06 [-0,17; 0,05] 0,309
sexoF 0,37 [-2,24; 2,98] 0,774
imc 0,04 [-0,29; 0,37] 0,806
# R² ajustado e diagnósticos
cat(sprintf("R² ajustado: %s\n", nv(summary(fit_qor48)$adj.r.squared, 3)))

R² ajustado: 0,198

shapiro.test(residuals(fit_qor48))
Shapiro-Wilk normality test

data: residuals(fit_qor48) W = 0.69833, p-value = 1.188e-07

car::ncvTest(fit_qor48)

Non-constant Variance Score Test Variance formula: ~ fitted.values Chisquare = 11.54788, Df = 1, p = 0.00067826

10.3 Modelo linear misto — trajetória do EVN em movimento

lmer(nrs ~ group * tempo + (1|id)) — random intercept por paciente. A ANOVA tipo III com graus de liberdade de Satterthwaite (via lmerTest) testa os efeitos principais e a interação grupo × tempo. As EMMs em cada momento permitem comparar grupos tempo a tempo.

de_mov <- dados %>%
  select(id, group, `NRS RPA m`, `NRS 24h m`, `NRS 48h m`) %>%
  pivot_longer(-c(id, group), names_to = "tempo", values_to = "nrs") %>%
  mutate(tempo = factor(dplyr::recode(tempo,
                                      "NRS RPA m" = "SRPA",
                                      "NRS 24h m" = "24h",
                                      "NRS 48h m" = "48h"),
                        levels = c("SRPA","24h","48h"))) %>%
  filter(!is.na(nrs))

fit_lmm_evn <- lmer(nrs ~ group * tempo + (1 | id), data = de_mov)

# Tabela ANOVA tipo III com Satterthwaite
anova_tab <- as.data.frame(anova(fit_lmm_evn)) %>%
  tibble::rownames_to_column("Termo") %>%
  transmute(
    Termo,
    `F`       = nv(`F value`, 2),
    `GL num`  = nv(NumDF, 1),
    `GL den`  = nv(DenDF, 1),
    `Valor-p` = ifelse(`Pr(>F)` < 0.001, "&lt;0,001", nv(`Pr(>F)`, 3))
  )
knitr::kable(anova_tab, align = c("l","c","c","c","c"),
             caption = "LMM — ANOVA tipo III (Satterthwaite) para EVN em movimento")
(#tab:lmm_evn_mov)LMM — ANOVA tipo III (Satterthwaite) para EVN em movimento
Termo F GL num GL den Valor-p
group 0,82 1,0 37,0 0,370
tempo 48,12 2,0 74,0 <0,001
group:tempo 0,51 2,0 74,0 0,601
# EMMs por tempo e contraste BMRA-CLO − BMRA em cada momento
emm_evn       <- emmeans(fit_lmm_evn, ~ group | tempo)
contr_evn_obj <- contrast(emm_evn, method = "pairwise")
contr_ev      <- as.data.frame(summary(contr_evn_obj, infer = c(TRUE, TRUE)))
contr_ev$estimate <- -contr_ev$estimate
tmp <- contr_ev$lower.CL; contr_ev$lower.CL <- -contr_ev$upper.CL; contr_ev$upper.CL <- -tmp

contr_tab <- contr_ev %>%
  transmute(
    Tempo                    = tempo,
    `Δ ajustada (CLO − BMRA)` = nv(estimate, 2),
    `IC 95%`                 = sprintf("[%s; %s]", nv(lower.CL, 2), nv(upper.CL, 2)),
    `Valor-p`                = ifelse(p.value < 0.001, "&lt;0,001", nv(p.value, 3))
  )
knitr::kable(contr_tab, align = c("l","c","c","c"),
             caption = "LMM — diferenças entre grupos em cada tempo (EVN movimento)")
(#tab:lmm_evn_mov)LMM — diferenças entre grupos em cada tempo (EVN movimento)
Tempo Δ ajustada (CLO − BMRA) IC 95% Valor-p
SRPA -0,19 [-1,08; 0,69] 0,662
24h -0,07 [-0,95; 0,81] 0,873
48h -0,59 [-1,48; 0,29] 0,183

11 Análises de Sensibilidade

O objetivo desta seção é verificar a robustez dos resultados sobre o consumo de fentanil através de diferentes métodos (Winsorização, teste de Yuen, permutação e bootstrap), garantindo que os achados não sejam fruto de outliers.

11.1 Fentanil (µg/kg)

df_fkg <- dados %>%
  filter(!is.na(group), is.finite(fentanyl_per_kg)) %>%
  select(group, fentanyl_val = fentanyl, fentanyl_per_kg)

wins_by_group <- function(x, g, trim = 0.05) {
  for (lv in levels(g)) {
    idx <- which(g == lv & is.finite(x))
    q   <- quantile(x[idx], c(trim, 1 - trim), na.rm = TRUE)
    x[idx] <- pmin(pmax(x[idx], q[1]), q[2])
  }
  x
}

# 1) t de Welch winsorizado (µg/kg)
x_wins <- wins_by_group(df_fkg$fentanyl_per_kg, df_fkg$group, trim = 0.05)
t.test(x_wins ~ df_fkg$group, var.equal = FALSE)
## 
##  Welch Two Sample t-test
## 
## data:  x_wins by df_fkg$group
## t = 5.6705, df = 26.455, p-value = 5.439e-06
## alternative hypothesis: true difference in means between group BMRA and group BMRA-CLO is not equal to 0
## 95 percent confidence interval:
##  0.3916251 0.8364061
## sample estimates:
##     mean in group BMRA mean in group BMRA-CLO 
##              1.4406338              0.8266182
# 2) Teste de Yuen (médias aparadas a 20%)
try(WRS2::yuen(fentanyl_per_kg ~ group, data = df_fkg, tr = 0.2), silent = TRUE)
## Call:
## WRS2::yuen(formula = fentanyl_per_kg ~ group, data = df_fkg, 
##     tr = 0.2)
## 
## Test statistic: 4.6112 (df = 17.4), p-value = 0.00024
## 
## Trimmed mean difference:  0.65968 
## 95 percent confidence interval:
## 0.3584     0.961 
## 
## Explanatory measure of effect size: 0.9
# 3) Teste de permutação (independência)
set.seed(123)
coin::independence_test(fentanyl_per_kg ~ group, data = df_fkg,
                        distribution = coin::approximate(B = 5000))
## 
##  Approximative General Independence Test
## 
## data:  fentanyl_per_kg by group (BMRA, BMRA-CLO)
## Z = 4.04, p-value < 2e-04
## alternative hypothesis: two.sided
# 4) Dose total — Mann–Whitney
wilcox.test(fentanyl_val ~ group, data = df_fkg, exact = FALSE, conf.int = TRUE)
## 
##  Wilcoxon rank sum test with continuity correction
## 
## data:  fentanyl_val by group
## W = 333, p-value = 1.589e-05
## alternative hypothesis: true location shift is not equal to 0
## 95 percent confidence interval:
##  49.99994 50.00001
## sample estimates:
## difference in location 
##               49.99992
# 5) Bootstrap BCa da diferença de médias (CLO − BMRA), estratificado por grupo
boot_diff <- function(d, i) {
  d <- d[i, ]
  mean(d$fentanyl_val[d$group == "BMRA-CLO"]) - mean(d$fentanyl_val[d$group == "BMRA"])
}
set.seed(123)
br <- boot::boot(df_fkg, boot_diff, R = 2000, strata = df_fkg$group)
boot::boot.ci(br, type = "bca")
## BOOTSTRAP CONFIDENCE INTERVAL CALCULATIONS
## Based on 2000 bootstrap replicates
## 
## CALL : 
## boot::boot.ci(boot.out = br, type = "bca")
## 
## Intervals : 
## Level       BCa          
## 95%   (-66.79, -31.74 )  
## Calculations and Intervals on Original Scale
# 6) Casos influentes — distância de Cook (leave-one-out)
fit_lm <- lm(fentanyl_per_kg ~ group, data = df_fkg)
inf_df <- df_fkg %>%
  mutate(id = row_number(), cooks = cooks.distance(fit_lm), influente = cooks > 4/n())

ggplot(inf_df, aes(id, cooks, color = influente)) +
  geom_segment(aes(xend = id, y = 0, yend = cooks), color = "gray") +
  geom_point(size = 3) +
  geom_hline(yintercept = 4/nrow(inf_df), linetype = "dashed", color = "red") +
  scale_color_manual(values = c("TRUE" = "#E74C3C", "FALSE" = "#2C3E50")) +
  labs(title = "Distância de Cook (leave-one-out)",
       subtitle = "Pontos acima da linha vermelha distorcem isoladamente a média do grupo",
       x = "Paciente (índice)", y = "Distância de Cook") +
  theme(legend.position = "none")