Cuando se desea comparar dos grupos (por ejemplo, dos tratamientos, dos poblaciones, antes/después, grupo control vs experimental), se utilizan pruebas de hipótesis para dos muestras. El objetivo es determinar si existe evidencia estadística de que los parámetros poblacionales (medias, proporciones, varianzas) son diferentes entre los dos grupos.

Tipos de comparaciones según el diseño

Diseño Descripción Ejemplo
Muestras independientes Los sujetos de un grupo no están relacionados con los del otro Comparar eficacia de dos fármacos en pacientes diferentes
Muestras pareadas (dependientes) Las observaciones están emparejadas (mismo sujeto en dos momentos, o sujetos emparejados por características) Medición de presión arterial antes y después de un tratamiento

Prueba de hipótesis para dos medias con suposición de varianzas desconocidas pero iguales (prueba t de Student para dos muestras independientes)

Cuando se comparan las medias de dos poblaciones independientes, se supone que ambas poblaciones son normales y que las varianzas son desconocidas pero iguales (\(\sigma_1^2 = \sigma_2^2 = \sigma^2\)).

Hipótesis (para un contraste bilateral): \[ H_0: \mu_1 = \mu_2 \qquad \text{vs.} \qquad H_1: \mu_1 \neq \mu_2 \]

Condición de validez: \[ \text{Normalidad en cada grupo} \quad \text{\&} \quad \text{independencia entre grupos} \]

Estadístico de prueba: \[ t = \frac{\bar{x}_1 - \bar{x}_2}{s_p \sqrt{\frac{1}{n_1} + \frac{1}{n_2}}} \] donde la varianza combinada es: \[ s_p^2 = \frac{(n_1-1)s_1^2 + (n_2-1)s_2^2}{n_1 + n_2 - 2} \] Bajo \(H_0\), \(t\) sigue una distribución t de Student con \(n_1 + n_2 - 2\) grados de libertad.

Regla de decisión (nivel \(\alpha\)): \[ \text{Rechazar } H_0 \text{ si } |t| > t_{\alpha/2, \, n_1+n_2-2} \]

Valor p (bilateral): \[ p\text{-valor} = 2 \cdot P(T > |t| \mid H_0) \]

Ejemplo en R

Comparación de dos centrifugadoras. Se sospecha que reportan mediciones distintas para la misma pintura. Se comparan las medias con varianza combinada.

# Datos del ejemplo 2.6
A <- c(4714, 4601, 4696, 4896, 4905, 4870, 4987, 5144, 3962, 4066, 4561, 4626, 4924)
B <- c(4295, 4271, 4326, 4530, 4618, 4779, 4752, 4744, 3764, 3797, 4401, 4339, 4700)

# Prueba t de Student (varianzas iguales)
t_test_igual <- t.test(A, B, var.equal = TRUE, alternative = "two.sided")

# Resultados
cat("Media A:", mean(A), "\n")
## Media A: 4688.615
cat("Media B:", mean(B), "\n")
## Media B: 4408.923
cat("\n--- Prueba t de Student (varianzas iguales) ---\n")
## 
## --- Prueba t de Student (varianzas iguales) ---
print(t_test_igual)
## 
##  Two Sample t-test
## 
## data:  A and B
## t = 2.1016, df = 24, p-value = 0.04627
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##    5.019674 554.364941
## sample estimates:
## mean of x mean of y 
##  4688.615  4408.923
# Extraer estadístico t y grados de libertad
t_stat <- t_test_igual$statistic
df <- t_test_igual$parameter
p_valor <- t_test_igual$p.value
alpha <- 0.05
t_crit <- qt(1 - alpha/2, df = df)

Gráfico

library(ggplot2)

# Datos para la curva t de Student con gl = df
x_vals <- seq(-5, 5, length = 300)
y_vals <- dt(x_vals, df = df)

# Regiones de rechazo
limite <- t_crit
region_rechazo_izq <- data.frame(x = x_vals[x_vals <= -limite],
                                 y = y_vals[x_vals <= -limite])
region_rechazo_der <- data.frame(x = x_vals[x_vals >= limite],
                                 y = y_vals[x_vals >= limite])

# Identificar si el estadístico cae en región de rechazo
color_rechazo <- ifelse(abs(t_stat) > limite, "red", "blue")
texto_rechazo <- ifelse(abs(t_stat) > limite, 
                        "Se rechaza H0", 
                        "No se rechaza H0")

ggplot() +
  geom_line(aes(x_vals, y_vals), color = "black", size = 1) +
  geom_area(data = region_rechazo_izq, aes(x, y), fill = "red", alpha = 0.4) +
  geom_area(data = region_rechazo_der, aes(x, y), fill = "red", alpha = 0.4) +
  geom_vline(xintercept = t_stat, color = color_rechazo, linetype = "dashed", size = 1) +
  geom_vline(xintercept = c(-limite, limite), color = "darkred", linetype = "dotted") +
  annotate("text", x = t_stat, y = 0.1, 
           label = paste("t =", round(t_stat, 2)), 
           color = color_rechazo, fontface = "bold") +
  annotate("text", x = limite + 0.5, y = 0.05, 
           label = "Región de rechazo", color = "darkred", size = 3.5) +
  annotate("text", x = -limite - 0.5, y = 0.05, 
           label = "Región de rechazo", color = "darkred", size = 3.5) +
  annotate("text", x = 0, y = 0.2, 
           label = texto_rechazo, 
           color = color_rechazo, size = 5, fontface = "bold") +
  annotate("text", x = 0, y = 0.1, 
           label = paste("Valor p =", round(p_valor, 4)), 
           color = "gray30", size = 4) +
  labs(title = "Prueba t bilateral para dos medias (varianzas iguales)",
       subtitle = paste("H0: μA = μB, H1: μA ≠ μB | α = 0.05 | gl =", df),
       x = "Estadístico t", y = "Densidad") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5, face = "bold"),
        plot.subtitle = element_text(hjust = 0.5))
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once per session.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

Prueba de hipótesis para dos medias sin suponer varianzas iguales (prueba t de Welch)

Cuando se comparan dos medias independientes sin asumir igualdad de varianzas, se utiliza la corrección de Welch.

Hipótesis (bilateral): \[ H_0: \mu_1 = \mu_2 \qquad \text{vs.} \qquad H_1: \mu_1 \neq \mu_2 \]

Condición de validez: \[ \text{Normalidad aproximada en cada grupo} \]

Estadístico de prueba: \[ t = \frac{\bar{x}_1 - \bar{x}_2}{\sqrt{\frac{s_1^2}{n_1} + \frac{s_2^2}{n_2}}} \]

Grados de libertad (aproximación de Welch-Satterthwaite): \[ \nu = \frac{\left( \frac{s_1^2}{n_1} + \frac{s_2^2}{n_2} \right)^2}{\frac{(s_1^2/n_1)^2}{n_1-1} + \frac{(s_2^2/n_2)^2}{n_2-1}} \]

Regla de decisión: \[ \text{Rechazar } H_0 \text{ si } |t| > t_{\alpha/2, \, \nu} \]

Ejemplo R

Mismos datos de las centrifugadoras sin asumir la igualdad de varianzas.

# Prueba t de Welch (varianzas desiguales)
t_test_welch <- t.test(A, B, var.equal = FALSE, alternative = "two.sided")

cat("--- Prueba t de Welch (varianzas no asumidas iguales) ---\n")
## --- Prueba t de Welch (varianzas no asumidas iguales) ---
print(t_test_welch)
## 
##  Welch Two Sample t-test
## 
## data:  A and B
## t = 2.1016, df = 23.983, p-value = 0.04627
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##    5.009104 554.375512
## sample estimates:
## mean of x mean of y 
##  4688.615  4408.923
# Extraer estadístico t y grados de libertad (aproximados de Welch)
t_stat <- t_test_welch$statistic
df_welch <- t_test_welch$parameter
p_valor <- t_test_welch$p.value
alpha <- 0.05
t_crit <- qt(1 - alpha/2, df = df_welch)

Gráfico

# Datos para la curva t de Student con gl = df_welch
x_vals <- seq(-5, 5, length = 300)
y_vals <- dt(x_vals, df = df_welch)

# Regiones de rechazo
limite <- t_crit
region_rechazo_izq <- data.frame(x = x_vals[x_vals <= -limite],
                                 y = y_vals[x_vals <= -limite])
region_rechazo_der <- data.frame(x = x_vals[x_vals >= limite],
                                 y = y_vals[x_vals >= limite])

# Identificar si el estadístico cae en región de rechazo
color_rechazo <- ifelse(abs(t_stat) > limite, "red", "blue")
texto_rechazo <- ifelse(abs(t_stat) > limite, 
                        "Se rechaza H0", 
                        "No se rechaza H0")

# Calcular el valor p para mostrar en el gráfico
p_label <- paste("Valor p =", round(p_valor, 4))

ggplot() +
  geom_line(aes(x_vals, y_vals), color = "black", size = 1) +
  geom_area(data = region_rechazo_izq, aes(x, y), fill = "red", alpha = 0.4) +
  geom_area(data = region_rechazo_der, aes(x, y), fill = "red", alpha = 0.4) +
  geom_vline(xintercept = t_stat, color = color_rechazo, linetype = "dashed", size = 1) +
  geom_vline(xintercept = c(-limite, limite), color = "darkred", linetype = "dotted") +
  annotate("text", x = t_stat, y = 0.12, 
           label = paste("t =", round(t_stat, 2)), 
           color = color_rechazo, fontface = "bold") +
  annotate("text", x = limite + 0.5, y = 0.05, 
           label = "Región de rechazo", color = "darkred", size = 3.5) +
  annotate("text", x = -limite - 0.5, y = 0.05, 
           label = "Región de rechazo", color = "darkred", size = 3.5) +
  annotate("text", x = 0, y = 0.22, 
           label = texto_rechazo, 
           color = color_rechazo, size = 5, fontface = "bold") +
  annotate("text", x = 0, y = 0.18, 
           label = p_label, 
           color = "gray30", size = 4) +
  labs(title = "Prueba t de Welch para dos medias (varianzas desiguales)",
       subtitle = paste("H0: μA = μB, H1: μA ≠ μB | α = 0.05 | gl ≈", round(df_welch, 2)),
       x = "Estadístico t", y = "Densidad") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5, face = "bold"),
        plot.subtitle = element_text(hjust = 0.5))

Prueba de igualdad de varianzas (prueba F de Fisher para dos varianzas)

Antes de decidir entre las pruebas t anteriores, a menudo se contrasta la homogeneidad de varianzas.

Hipótesis: \[ H_0: \sigma_1^2 = \sigma_2^2 \qquad \text{vs.} \qquad H_1: \sigma_1^2 \neq \sigma_2^2 \]

Condición de validez: \[ \text{Normalidad en ambas poblaciones} \]

Estadístico de prueba: \[ F = \frac{s_1^2}{s_2^2} \quad \text{(donde } s_1^2 \geq s_2^2\text{, colocando la varianza mayor en el numerador)} \]

Bajo \(H_0\), \(F\) sigue una distribución F de Fisher con \(\nu_1 = n_1-1\) y \(\nu_2 = n_2-1\) grados de libertad.

Regla de decisión (bilateral, nivel \(\alpha\)): \[ \text{Rechazar } H_0 \text{ si } F > F_{\alpha/2, \, \nu_1, \nu_2} \]

Valor p (bilateral): \[ p\text{-valor} = 2 \cdot P(F > F_{\text{obs}} \mid H_0) \]

Ejemplo R

Verificar si las varianzas de las dos centrifugadoras son iguales, antes de decidir qué prueba t usar.

# Prueba F de varianzas
var_test <- var.test(A, B, alternative = "two.sided")

cat("--- Prueba F de igualdad de varianzas ---\n")
## --- Prueba F de igualdad de varianzas ---
print(var_test)
## 
##  F test to compare two variances
## 
## data:  A and B
## F = 1.0554, num df = 12, denom df = 12, p-value = 0.9271
## alternative hypothesis: true ratio of variances is not equal to 1
## 95 percent confidence interval:
##  0.3220441 3.4589292
## sample estimates:
## ratio of variances 
##           1.055428
# Extraer estadístico F y grados de libertad
F_stat <- var_test$statistic
df1 <- var_test$parameter[1]  # grados de libertad numerador
df2 <- var_test$parameter[2]  # grados de libertad denominador
p_valor <- var_test$p.value
alpha <- 0.05

# Valores críticos (cola inferior y superior)
F_crit_sup <- qf(1 - alpha/2, df1, df2)
F_crit_inf <- qf(alpha/2, df1, df2)

# Varianzas muestrales
var_A <- var(A)
var_B <- var(B)

Gráfico

# Datos para la curva F con df1 y df2
x_vals <- seq(0, 5, length = 500)
y_vals <- df(x_vals, df1 = df1, df2 = df2)

# Regiones de rechazo (bilateral)
# Cola superior (derecha)
region_rechazo_sup <- data.frame(x = x_vals[x_vals >= F_crit_sup],
                                  y = y_vals[x_vals >= F_crit_sup])

# Cola inferior (izquierda)
region_rechazo_inf <- data.frame(x = x_vals[x_vals <= F_crit_inf],
                                  y = y_vals[x_vals <= F_crit_inf])

# Identificar si el estadístico cae en región de rechazo
color_rechazo <- ifelse(F_stat > F_crit_sup | F_stat < F_crit_inf, "red", "blue")
texto_rechazo <- ifelse(F_stat > F_crit_sup | F_stat < F_crit_inf, 
                        "Se rechaza H0: las varianzas son diferentes", 
                        "No se rechaza H0: no hay evidencia de diferencia de varianzas")

# Crear el gráfico
p <- ggplot() +
  geom_line(aes(x_vals, y_vals), color = "black", size = 1) +
  geom_area(data = region_rechazo_inf, aes(x, y), fill = "red", alpha = 0.4) +
  geom_area(data = region_rechazo_sup, aes(x, y), fill = "red", alpha = 0.4) +
  geom_vline(xintercept = F_stat, color = color_rechazo, linetype = "dashed", size = 1) +
  geom_vline(xintercept = F_crit_inf, color = "darkred", linetype = "dotted") +
  geom_vline(xintercept = F_crit_sup, color = "darkred", linetype = "dotted") +
  annotate("text", x = F_stat, y = 0.5, 
           label = paste("F =", round(F_stat, 3)), 
           color = color_rechazo, fontface = "bold", size = 4) +
  annotate("text", x = F_crit_sup + 0.3, y = 0.2, 
           label = "Región de rechazo\n(cola derecha)", color = "darkred", size = 3.5) +
  annotate("text", x = F_crit_inf - 0.3, y = 0.05, 
           label = "Región de rechazo\n(cola izquierda)", color = "darkred", size = 3.5) +
  annotate("text", x = 2.5, y = 0.8, 
           label = texto_rechazo, 
           color = color_rechazo, size = 4.5, fontface = "bold") +
  annotate("text", x = 2.5, y = 0.7, 
           label = paste("Valor p =", round(p_valor, 4)), 
           color = "gray30", size = 4) +
  labs(title = "Prueba F de igualdad de varianzas",
       subtitle = paste("H0: σ²A = σ²B, H1: σ²A ≠ σ²B | α = 0.05 | gl1 =", df1, ", gl2 =", df2),
       x = "Estadístico F", y = "Densidad") +
  xlim(0, 5) +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5, face = "bold"),
        plot.subtitle = element_text(hjust = 0.5))

# Ajustar límites del eje x si F_stat es muy grande
if(F_stat > 4.5) {
  p <- p + xlim(0, F_stat + 1)
}

print(p)

Comparación de dos proporciones (prueba Z para dos proporciones independientes)

Para comparar las proporciones \(p_1\) y \(p_2\) de dos poblaciones independientes, con muestras grandes.

Hipótesis (bilateral): \[ H_0: p_1 = p_2 \qquad \text{vs.} \qquad H_1: p_1 \neq p_2 \]

Condición de validez: \[ n_1\hat{p}_1 \geq 5,\ n_1(1-\hat{p}_1) \geq 5,\quad n_2\hat{p}_2 \geq 5,\ n_2(1-\hat{p}_2) \geq 5 \]

Estadístico de prueba: \[ Z = \frac{\hat{p}_1 - \hat{p}_2}{\sqrt{\hat{p}(1-\hat{p})\left(\frac{1}{n_1} + \frac{1}{n_2}\right)}} \] donde: \[ \hat{p}_1 = \frac{x_1}{n_1},\quad \hat{p}_2 = \frac{x_2}{n_2},\quad \hat{p} = \frac{x_1 + x_2}{n_1 + n_2} \] Bajo \(H_0\), \(Z\) sigue aproximadamente una distribución normal estándar.

Regla de decisión: \[ \text{Rechazar } H_0 \text{ si } |Z| > z_{\alpha/2} \]

Ejemplo en R

Se comparan dos fármacos para aliviar cierta enfermedad. Se integran dos grupos formados por \(n_{1} = n_{2} = 100\). A cada grupo se le suministró un fármaco diferentes. En el primer grupo se aliviaron \(65\) personas, y en el segundo grupo se aliviaron \(75\) personas.

# Datos
n1 <- 100
n2 <- 100
x1 <- 65
x2 <- 75

# Prueba estadistica
prop_test <- prop.test(c(x1, x2), c(n1, n2), correct = FALSE)
cat("\n--- Resultado ---\n")
## 
## --- Resultado ---
print(prop_test)
## 
##  2-sample test for equality of proportions without continuity correction
## 
## data:  c(x1, x2) out of c(n1, n2)
## X-squared = 2.381, df = 1, p-value = 0.1228
## alternative hypothesis: two.sided
## 95 percent confidence interval:
##  -0.22626185  0.02626185
## sample estimates:
## prop 1 prop 2 
##   0.65   0.75
# Cálculo manual de estadísticos
p1_hat <- x1 / n1
p2_hat <- x2 / n2
p_hat <- (x1 + x2) / (n1 + n2)

# Estadístico Z
Z <- (p1_hat - p2_hat) / sqrt(p_hat * (1 - p_hat) * (1/n1 + 1/n2))

# Valor p bilateral
p_valor_manual <- 2 * (1 - pnorm(abs(Z)))

# Valor crítico
alpha <- 0.05
z_crit <- qnorm(1 - alpha/2)

Gráfico

# Datos para la curva N(0,1)
x_vals <- seq(-4, 4, length = 300)
y_vals <- dnorm(x_vals)

# Regiones de rechazo
limite <- z_crit
region_rechazo_izq <- data.frame(x = x_vals[x_vals <= -limite],
                                 y = y_vals[x_vals <= -limite])
region_rechazo_der <- data.frame(x = x_vals[x_vals >= limite],
                                 y = y_vals[x_vals >= limite])

# Identificar si el estadístico cae en región de rechazo
color_rechazo <- ifelse(abs(Z) > limite, "red", "blue")
texto_rechazo <- ifelse(abs(Z) > limite, 
                        "Se rechaza H0: las proporciones son diferentes", 
                        "No se rechaza H0: no hay diferencia significativa")

# Intervalos de confianza para cada proporción
IC_p1 <- prop.test(x1, n1, conf.level = 0.95)$conf.int
IC_p2 <- prop.test(x2, n2, conf.level = 0.95)$conf.int

ggplot() +
  geom_line(aes(x_vals, y_vals), color = "black", size = 1) +
  geom_area(data = region_rechazo_izq, aes(x, y), fill = "red", alpha = 0.4) +
  geom_area(data = region_rechazo_der, aes(x, y), fill = "red", alpha = 0.4) +
  geom_vline(xintercept = Z, color = color_rechazo, linetype = "dashed", size = 1) +
  geom_vline(xintercept = c(-limite, limite), color = "darkred", linetype = "dotted") +
  annotate("text", x = Z, y = 0.15, 
           label = paste("Z =", round(Z, 3)), 
           color = color_rechazo, fontface = "bold", size = 4.5) +
  annotate("text", x = limite + 0.4, y = 0.08, 
           label = "Región de rechazo\n(cola derecha)", color = "darkred", size = 3.5) +
  annotate("text", x = -limite - 0.4, y = 0.08, 
           label = "Región de rechazo\n(cola izquierda)", color = "darkred", size = 3.5) +
  annotate("text", x = 0, y = 0.25, 
           label = texto_rechazo, 
           color = color_rechazo, size = 4.5, fontface = "bold") +
  annotate("text", x = 0, y = 0.2, 
           label = paste("Valor p =", round(p_valor_manual, 4)), 
           color = "gray30", size = 4) +
  labs(title = "Prueba Z para dos proporciones",
       subtitle = paste("H0: p1 = p2, H1: p1 ≠ p2 | α = 0.05\n",
                        "p1 =", round(p1_hat, 3), "| p2 =", round(p2_hat, 3), 
                        "| Diferencia =", round(p1_hat - p2_hat, 3)),
       x = "Estadístico Z", y = "Densidad") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5, face = "bold"),
        plot.subtitle = element_text(hjust = 0.5))

Poblaciones pareadas (prueba t para muestras pareadas)

Cuando los datos están apareados (mediciones pre-post, sujetos como su propio control), se analiza la diferencia \(d_i = x_{i1} - x_{i2}\).

Hipótesis (bilateral): \[ H_0: \mu_d = 0 \qquad \text{vs.} \qquad H_1: \mu_d \neq 0 \] donde \(\mu_d\) es la media poblacional de las diferencias.

Condición de validez: \[ \text{Diferencias } d_i \text{ aproximadamente normales} \]

Estadístico de prueba: \[ t = \frac{\bar{d}}{s_d / \sqrt{n}} \] con: \[ \bar{d} = \frac{1}{n}\sum_{i=1}^n d_i,\qquad s_d^2 = \frac{1}{n-1}\sum_{i=1}^n (d_i - \bar{d})^2 \]

Bajo \(H_0\), \(t\) sigue una distribución t de Student con \(n-1\) grados de libertad.

Regla de decisión: \[ \text{Rechazar } H_0 \text{ si } |t| > t_{\alpha/2, \, n-1} \]

Valor p (bilateral): \[ p\text{-valor} = 2 \cdot P(T > |t| \mid H_0) \]

Ejemplo R

Comparación de método actual vs nuevo en 18 discos. Se mide densidad mínima de metal.

# Datos pareados (18 discos)
actual <- c(1.88, 1.84, 1.83, 1.90, 2.19, 1.89, 2.27, 2.03, 1.96,
            1.98, 1.99, 1.89, 1.78, 1.92, 2.02, 2.00, 1.95, 2.05)
nuevo <- c(1.87, 1.90, 1.85, 1.88, 2.18, 1.87, 2.23, 1.97, 2.00,
           1.98, 1.99, 1.89, 1.78, 1.92, 2.02, 2.00, 1.95, 2.05)

# Prueba t pareada
t_test_pareado <- t.test(actual, nuevo, paired = TRUE, alternative = "two.sided")

Gráfico

# Cálculo manual de las diferencias
diferencias <- actual - nuevo
d_bar <- mean(diferencias)
sd_d <- sd(diferencias)
n <- length(diferencias)
gl <- n - 1

# Estadístico t manual
t_manual <- d_bar / (sd_d / sqrt(n))

# Valor crítico
alpha <- 0.05
t_crit <- qt(1 - alpha/2, df = gl)

# Valor p manual
p_valor_manual <- 2 * (1 - pt(abs(t_manual), df = gl))

# Datos para la curva t de Student con gl = 17
x_vals <- seq(-5, 5, length = 300)
y_vals <- dt(x_vals, df = gl)

# Regiones de rechazo
limite <- t_crit
region_rechazo_izq <- data.frame(x = x_vals[x_vals <= -limite],
                                 y = y_vals[x_vals <= -limite])
region_rechazo_der <- data.frame(x = x_vals[x_vals >= limite],
                                 y = y_vals[x_vals >= limite])

# Identificar si el estadístico cae en región de rechazo
color_rechazo <- ifelse(abs(t_manual) > limite, "red", "blue")
texto_rechazo <- ifelse(abs(t_manual) > limite, 
                        "Se rechaza H0: hay diferencia entre métodos", 
                        "No se rechaza H0: no hay diferencia significativa")

ggplot() +
  geom_line(aes(x_vals, y_vals), color = "black", size = 1) +
  geom_area(data = region_rechazo_izq, aes(x, y), fill = "red", alpha = 0.4) +
  geom_area(data = region_rechazo_der, aes(x, y), fill = "red", alpha = 0.4) +
  geom_vline(xintercept = t_manual, color = color_rechazo, linetype = "dashed", size = 1) +
  geom_vline(xintercept = c(-limite, limite), color = "darkred", linetype = "dotted") +
  annotate("text", x = t_manual, y = 0.15, 
           label = paste("t =", round(t_manual, 3)), 
           color = color_rechazo, fontface = "bold", size = 4.5) +
  annotate("text", x = limite + 0.4, y = 0.08, 
           label = "Región de rechazo\n(cola derecha)", color = "darkred", size = 3.5) +
  annotate("text", x = -limite - 0.4, y = 0.08, 
           label = "Región de rechazo\n(cola izquierda)", color = "darkred", size = 3.5) +
  annotate("text", x = 0, y = 0.25, 
           label = texto_rechazo, 
           color = color_rechazo, size = 4.5, fontface = "bold") +
  annotate("text", x = 0, y = 0.2, 
           label = paste("Valor p =", round(p_valor_manual, 4)), 
           color = "gray30", size = 4) +
  annotate("text", x = 0, y = 0.155, 
           label = paste("d̄ =", round(d_bar, 5)), 
           color = "gray30", size = 3.5) +
  labs(title = "Prueba t para muestras pareadas",
       subtitle = paste("H0: μd = 0, H1: µd ≠ 0 | α = 0.05 | gl =", gl),
       x = "Estadístico t", y = "Densidad") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5, face = "bold"),
        plot.subtitle = element_text(hjust = 0.5))