Cómo usar este notebook

Este documento es un material de estudio guiado. Cada prueba sigue siempre el mismo recorrido, para que aprendas a razonar y no solo a ejecutar una función:

  1. Idea intuitiva: qué pregunta responde la prueba.
  2. Supuestos e hipótesis: cuándo es válida y qué se contrasta.
  3. Estadístico y fórmulas: con la demostración de los resultados principales.
  4. Cálculo paso a paso “a mano” en R: cada fórmula se traduce en una línea de código.
  5. Función automática de R: confirma que el cálculo manual es correcto.
  6. Interpretación y reporte: cómo se escribe la conclusión en un informe.
  7. Ejercicio para practicar.

Instrucciones prácticas

  • Abre este archivo en RStudio. Puedes ejecutar cada bloque de código (las zonas grises) con el botón verde ▶ o con Ctrl + Shift + Enter, o generar el informe completo con Knit.
  • Solo se usa R base: no necesitas instalar paquetes, salvo rmarkdown para el botón Knit.
  • La base del taller ya viene incluida en este archivo. Al compilar se guarda una copia llamada encuesta_salud.csv en tu carpeta.
  • En todo el documento usaremos un nivel de significancia \(\alpha = 0.05\).
Sesión Tema Funciones de R
9.1 Prueba de los signos y prueba de Wilcoxon binom.test(), wilcox.test(paired = TRUE)
9.2 Prueba U de Mann-Whitney wilcox.test()
10.1 Chi-cuadrado de independencia y prueba exacta de Fisher chisq.test(), fisher.test()
10.2 Taller con una encuesta de salud pública todas las anteriores
11.1 Limitaciones en muestras pequeñas simulación de potencia
12.1–12.2 Evaluación parcial y solucionario todas las anteriores

1 Ideas previas que necesitamos

1.1 ¿Qué significa “no paramétrico”?

Una prueba paramétrica (por ejemplo, la prueba \(t\)) supone que los datos provienen de una familia de distribuciones conocida, normalmente la normal, y contrasta sus parámetros (\(\mu\), \(\sigma\)). Una prueba no paramétrica hace supuestos mucho más débiles: por lo general solo que las observaciones son independientes y provienen de una distribución continua.

¿Cómo lo logra? Trabajando con los signos o con los rangos (el orden) de los datos en lugar de sus valores. La distribución de los rangos bajo \(H_0\) no depende de la forma de la distribución original. Por eso estas pruebas se llaman también de distribución libre.

Cuándo conviene usarlas:

  • Variables asimétricas con valores extremos: ingresos, salarios, gasto, tiempos de espera.
  • Datos ordinales: escalas de satisfacción o Likert.
  • Muestras pequeñas, en las que no se puede verificar la normalidad.
  • Variables categóricas, organizadas en tablas de contingencia.

1.2 Los rangos y el tratamiento de los empates

El rango de una observación es su posición cuando los datos se ordenan de menor a mayor. Si dos o más valores son iguales (un empate), cada uno recibe el promedio de las posiciones que ocupan. Veámoslo en R:

x <- c(40, 60, 20, 60, 90, 60)
data.frame(valor = x, rango = rank(x))
valor rango
40 2
60 4
20 1
60 4
90 6
60 4

Los tres valores 60 ocupan las posiciones 3, 4 y 5. Por eso cada uno recibe el rango \((3+4+5)/3 = 4\). Observa una propiedad útil: la suma de los rangos de \(n\) datos siempre es

\[1 + 2 + \cdots + n = \frac{n(n+1)}{2}.\]

c(suma_rangos = sum(rank(x)), formula = length(x) * (length(x) + 1) / 2)
#> suma_rangos     formula 
#>          21          21

1.3 El p-valor y el tamaño del efecto

  • El p-valor es la probabilidad, suponiendo que \(H_0\) es cierta, de obtener un resultado tan extremo o más que el observado. Si \(p < \alpha\), rechazamos \(H_0\).
  • El p-valor no mide la magnitud del efecto. Con muestras grandes, una diferencia mínima puede ser “significativa”; con muestras pequeñas, una diferencia importante puede no serlo.
  • Por eso siempre reportaremos también un tamaño del efecto y un estimador de la diferencia (el estimador de Hodges-Lehmann).

1.4 Funciones auxiliares

R no tiene una función directa para la prueba de los signos ni para el estimador de Hodges-Lehmann. Las definimos una sola vez aquí y las usaremos en todo el documento.

# Estimador de Hodges-Lehmann para una muestra (o para diferencias pareadas):
# mediana de todos los promedios de Walsh (d_i + d_j)/2 con i <= j.
hl_1m <- function(d) {
  w <- outer(d, d, "+") / 2
  median(w[upper.tri(w, diag = TRUE)])
}

# Estimador de Hodges-Lehmann del desplazamiento entre dos muestras:
# mediana de todas las diferencias x_i - y_j.
hl_2m <- function(x, y) median(outer(x, y, "-"))

# Prueba de los signos para la mediana: cuenta los signos + y -, descarta los
# empates con m0 y aplica una prueba binomial con p = 1/2.
prueba_signos <- function(x, m0 = 0, alternative = "two.sided") {
  d <- x - m0
  pos <- sum(d > 0); neg <- sum(d < 0)
  binom.test(pos, pos + neg, p = 0.5, alternative = alternative)
}

2 Sesión 9.1 — Prueba de los signos y prueba de Wilcoxon

2.1 El caso: ingresos antes y después de una intervención

Un programa municipal de capacitación productiva se aplicó a 12 hogares. Se registró el ingreso mensual (S/) de cada hogar antes y después de la intervención. La pregunta es: ¿aumentó el ingreso típico de los hogares?

Los datos son pareados: cada hogar se mide dos veces. Por eso no comparamos dos grupos, sino que analizamos la diferencia de cada hogar:

\[D_i = \text{post}_i - \text{pre}_i, \qquad i = 1, \dots, 12.\]

pre  <- c(820, 950, 1100, 780, 1250, 900, 1010, 870, 1500, 990, 1120, 760)
post <- c(900, 1010, 1080, 850, 1400, 960, 1150, 870, 1620, 1050, 1180, 800)
d <- post - pre
data.frame(hogar = 1:12, pre, post, d, signo = sign(d))
hogar pre post d signo
1 820 900 80 1
2 950 1010 60 1
3 1100 1080 -20 -1
4 780 850 70 1
5 1250 1400 150 1
6 900 960 60 1
7 1010 1150 140 1
8 870 870 0 0
9 1500 1620 120 1
10 990 1050 60 1
11 1120 1180 60 1
12 760 800 40 1
c(mediana_pre = median(pre), mediana_post = median(post), mediana_d = median(d))
#>  mediana_pre mediana_post    mediana_d 
#>          970         1030           60

Primera lectura: casi todas las diferencias son positivas, una es negativa (hogar 3) y una es cero (hogar 8). Además hay empates en las diferencias: cuatro hogares aumentaron exactamente S/ 60. Ambas situaciones son frecuentes en datos reales y veremos cómo se tratan.

2.2 Prueba de los signos

2.2.1 Idea intuitiva

Si el programa no tuviera efecto, cada hogar tendría la misma probabilidad de aumentar o de disminuir su ingreso, como al lanzar una moneda. Si observamos “demasiados” aumentos para que sean obra del azar, concluimos que el ingreso mediano aumentó.

2.2.2 Supuestos e hipótesis

  • Las diferencias \(D_1, \dots, D_n\) son independientes (hogares distintos).
  • Provienen de una distribución continua con mediana \(M\).
  • No se requiere normalidad ni simetría.

\[H_0: M = 0 \qquad \text{frente a} \qquad H_1: M > 0 \quad (\text{el ingreso aumentó}).\]

2.2.3 El estadístico y su distribución (demostración)

Sea \(B\) el número de diferencias positivas entre las \(n^*\) diferencias no nulas.

Resultado. Bajo \(H_0\), \(B \sim \text{Binomial}\left(n^*, \tfrac12\right)\).

Demostración. Si la mediana de \(D\) es 0, entonces por definición de mediana (y porque \(D\) es continua): \[P(D_i > 0) = P(D_i < 0) = \tfrac12 .\] Definamos \(I_i = 1\) si \(D_i > 0\) e \(I_i = 0\) si \(D_i < 0\). Cada \(I_i\) es una variable de Bernoulli con \(p = \tfrac12\), y las \(I_i\) son independientes porque las \(D_i\) lo son. Entonces \(B = \sum_{i=1}^{n^*} I_i\) es una suma de \(n^*\) Bernoulli independientes con la misma \(p\), es decir, una binomial: \(B \sim \text{Binomial}(n^*, \tfrac12)\). \(\blacksquare\)

¿Y los ceros? Una diferencia igual a cero no aporta información sobre la dirección del cambio. Por eso se descartan y se trabaja con las \(n^*\) diferencias restantes.

P-valor (alternativa “mayor”). Es la probabilidad de observar \(b_{\text{obs}}\) o más signos positivos: \[p = P(B \ge b_{\text{obs}}) = \sum_{k = b_{\text{obs}}}^{n^*} \binom{n^*}{k}\left(\frac12\right)^{n^*}.\]

Muestras grandes (\(n^* > 25\)). Como \(E(B) = n^*/2\) y \(\mathrm{Var}(B) = n^*/4\): \[Z = \frac{B - n^*/2}{\sqrt{n^*}/2} \approx N(0,1).\]

2.2.4 Cálculo paso a paso

# Paso 1: contar signos (los ceros se descartan)
b     <- sum(d > 0)        # signos +
neg   <- sum(d < 0)        # signos -
n_est <- b + neg           # n* = diferencias no nulas
c(positivos = b, negativos = neg, ceros = sum(d == 0), n_est = n_est)
#> positivos negativos     ceros     n_est 
#>        10         1         1        11
# Paso 2: p-valor exacto con la fórmula binomial: P(B >= 10) con n* = 11
p_manual <- sum(choose(n_est, b:n_est) * 0.5^n_est)
p_manual
#> [1] 0.00585938
# lo mismo con la función de probabilidad binomial de R
sum(dbinom(b:n_est, size = n_est, prob = 0.5))
#> [1] 0.00585938

Es decir: \[p = \frac{\binom{11}{10} + \binom{11}{11}}{2^{11}} = \frac{11 + 1}{2048} = \frac{12}{2048} \approx 0.00586.\]

# Distribución de B bajo H0 y región del p-valor
k <- 0:n_est
barplot(dbinom(k, n_est, 0.5), names.arg = k,
        col = ifelse(k >= b, "#80162a", "grey75"), border = NA,
        main = "Distribución de B bajo H0: Binomial(11; 0.5)",
        xlab = "Número de signos positivos (B)", ylab = "Probabilidad")
legend("topleft", fill = "#80162a", legend = "Región del p-valor: B >= 10", bty = "n")

2.2.5 Confirmación con la función de R

prueba_signos(d, alternative = "greater")
#> 
#>  Exact binomial test
#> 
#> data:  pos and pos + neg
#> number of successes = 10, number of trials = 11, p-value = 0.00586
#> alternative hypothesis: true probability of success is greater than 0.5
#> 95 percent confidence interval:
#>  0.635641 1.000000
#> sample estimates:
#> probability of success 
#>               0.909091

Decisión: \(p = 0.0059 < 0.05\), así que rechazamos \(H_0\). Hay evidencia de que la mediana del ingreso aumentó.

Limitación: la prueba de los signos solo usa la dirección del cambio. Un hogar que ganó S/ 150 más cuenta igual que uno que ganó S/ 40 más. La prueba de Wilcoxon aprovecha también la magnitud.

2.3 Prueba de Wilcoxon de rangos con signo

2.3.1 Idea intuitiva

Ordenamos las diferencias por su tamaño (valor absoluto). Si el programa no tuviera efecto, las diferencias grandes serían positivas o negativas con igual probabilidad. Si las diferencias grandes son casi todas positivas, eso es evidencia de que el ingreso aumentó.

2.3.2 Supuestos e hipótesis

  • Diferencias independientes, de una distribución continua y simétrica alrededor de su mediana \(M\).
  • La simetría es el supuesto adicional respecto de la prueba de los signos.

\[H_0: M = 0 \qquad H_1: M > 0.\]

2.3.3 Procedimiento

  1. Calcular \(D_i\) y descartar los \(D_i = 0\); quedan \(n\) diferencias.
  2. Ordenar los \(|D_i|\) y asignar rangos \(1, \dots, n\) (rangos promedio si hay empates).
  3. Calcular \(W^+ =\) suma de los rangos de las diferencias positivas y \(W^- =\) suma de los rangos de las negativas. Siempre se cumple \(W^+ + W^- = \frac{n(n+1)}{2}\).

2.3.4 Media y varianza de \(W^+\) bajo \(H_0\) (demostración)

Sin empates, los rangos son \(1, 2, \dots, n\). Definamos \(I_i = 1\) si la diferencia con rango \(i\) es positiva y \(I_i = 0\) si es negativa. Entonces \[W^+ = \sum_{i=1}^{n} i \cdot I_i .\] Bajo \(H_0\) y por la simetría, cada signo es positivo con probabilidad \(\tfrac12\), de forma independiente de su rango. Por tanto \(E(I_i) = \tfrac12\) y \(\mathrm{Var}(I_i) = \tfrac14\), y:

\[E(W^+) = \sum_{i=1}^{n} i \cdot \frac12 = \frac12 \cdot \frac{n(n+1)}{2} = \frac{n(n+1)}{4},\]

\[\mathrm{Var}(W^+) = \sum_{i=1}^{n} i^2 \cdot \frac14 = \frac14 \cdot \frac{n(n+1)(2n+1)}{6} = \frac{n(n+1)(2n+1)}{24}. \qquad \blacksquare\]

Aquí usamos las sumas conocidas \(\sum i = \frac{n(n+1)}{2}\) y \(\sum i^2 = \frac{n(n+1)(2n+1)}{6}\).

Corrección por empates. Si hay grupos de valores empatados de tamaños \(t_1, t_2, \dots\), la varianza disminuye: \[\mathrm{Var}(W^+) = \frac{n(n+1)(2n+1)}{24} - \frac{\sum_j (t_j^3 - t_j)}{48}.\]

Estadístico estandarizado (con corrección por continuidad de \(0.5\)): \[Z = \frac{W^+ - E(W^+) - 0.5}{\sqrt{\mathrm{Var}(W^+)}} \approx N(0,1).\]

2.3.5 Cálculo paso a paso

# Paso 1: descartar las diferencias nulas
dz <- d[d != 0]
n  <- length(dz)

# Paso 2: rangos de los valores absolutos (rango promedio en los empates)
rangos <- rank(abs(dz))
tabla_w <- data.frame(d = dz, abs_d = abs(dz), rango = rangos,
                      signo = ifelse(dz > 0, "+", "-"))
tabla_w[order(tabla_w$abs_d), ]
d abs_d rango signo
3 -20 20 1.0 -
11 40 40 2.0 +
2 60 60 4.5 +
6 60 60 4.5 +
9 60 60 4.5 +
10 60 60 4.5 +
4 70 70 7.0 +
1 80 80 8.0 +
8 120 120 9.0 +
7 140 140 10.0 +
5 150 150 11.0 +
# Paso 3: sumas de rangos
W_mas   <- sum(rangos[dz > 0])
W_menos <- sum(rangos[dz < 0])
c(n = n, W_mas = W_mas, W_menos = W_menos, comprobacion = n * (n + 1) / 2)
#>            n        W_mas      W_menos comprobacion 
#>           11           65            1           66

Los cuatro valores \(|D| = 60\) ocupan las posiciones 3 a 6, así que cada uno recibe el rango \((3+4+5+6)/4 = 4.5\). La única diferencia negativa (\(-20\)) tiene el rango más pequeño: el único hogar que perdió ingreso fue el que menos cambió.

# Paso 4: media y varianza bajo H0, con corrección por empates
E_W <- n * (n + 1) / 4
t_j <- table(abs(dz))                  # tamaños de los grupos de empates
V_W <- n * (n + 1) * (2 * n + 1) / 24 - sum(t_j^3 - t_j) / 48
c(E_W = E_W, Var_sin_empates = n * (n + 1) * (2 * n + 1) / 24, Var_con_empates = V_W)
#>             E_W Var_sin_empates Var_con_empates 
#>           33.00          126.50          125.25
# Paso 5: estadístico Z y p-valor unilateral (cola derecha)
Z <- (W_mas - E_W - 0.5) / sqrt(V_W)
c(Z = Z, p_valor = pnorm(Z, lower.tail = FALSE))
#>          Z    p_valor 
#> 2.81463243 0.00244165

Sustituyendo los valores: \[E(W^+) = \frac{11 \cdot 12}{4} = 33, \qquad \mathrm{Var}(W^+) = \frac{11 \cdot 12 \cdot 23}{24} - \frac{4^3 - 4}{48} = 126.5 - 1.25 = 125.25,\] \[Z = \frac{65 - 33 - 0.5}{\sqrt{125.25}} = 2.815, \qquad p = P(Z \ge 2.815) = 0.00244.\]

2.3.6 Confirmación con la función de R

Como hay ceros y empates, R no puede usar la distribución exacta y aplica la aproximación normal que acabamos de calcular:

wilcox.test(post, pre, paired = TRUE, alternative = "greater",
            exact = FALSE, correct = TRUE)
#> 
#>  Wilcoxon signed rank test with continuity correction
#> 
#> data:  post and pre
#> V = 65, p-value = 0.00244
#> alternative hypothesis: true location shift is greater than 0

R llama \(V\) al estadístico \(W^+\). Obtuvimos el mismo valor: \(V = 65\) y \(p = 0.00244\).

Nota sobre la distribución exacta. Sin empates, para \(n\) pequeño se usa la distribución exacta de \(W^+\), que se obtiene contando los \(2^n\) patrones de signos igualmente probables. Por ejemplo, con \(n = 11\) y sin empates, solo 2 de los 2048 patrones dan \(W^+ \geq 65\):

psignrank(64, n = 11, lower.tail = FALSE)      # P(W+ >= 65) = 2/2048
#> [1] 0.000976562

2.3.7 Estimación y tamaño del efecto

Estimador de Hodges-Lehmann. Se calcula la mediana de los promedios de Walsh \(\frac{D_i + D_j}{2}\) para todos los pares \(i \le j\). Estima el cambio típico y es robusto frente a valores extremos:

HL <- hl_1m(dz)
r  <- Z / sqrt(n)            # tamaño del efecto
c(Hodges_Lehmann = HL, r = r)
#> Hodges_Lehmann              r 
#>      70.000000       0.848644

Tamaño del efecto \(r = Z/\sqrt{n}\). Como referencia (Cohen): \(0.1\) es pequeño, \(0.3\) mediano y \(0.5\) grande. Aquí \(r = 0.85\): el efecto es grande.

2.3.8 Visualización

par(mfrow = c(1, 2), mar = c(4, 4, 2.5, 1))
matplot(rbind(1, 2), rbind(pre, post), type = "b", pch = 19, lty = 1,
        col = ifelse(post > pre, "darkgreen", ifelse(post < pre, "firebrick", "grey50")),
        xaxt = "n", xlab = "", ylab = "Ingreso (S/)", main = "Ingreso por hogar")
axis(1, at = 1:2, labels = c("Antes", "Después"))
plot(sort(d), type = "h", lwd = 3, col = "#1856a0", ylab = "S/",
     xlab = "Hogares (ordenados)", main = "Diferencias post - pre"); abline(h = 0)

2.3.9 Conclusión e informe

Prueba de los signos Prueba de Wilcoxon
Usa solo la dirección dirección y magnitud
Supuesto adicional ninguno simetría de \(D\)
Estadístico \(B = 10\) de \(n^* = 11\) \(W^+ = 65\)
p-valor (unilateral) 0.0059 0.0024

Redacción sugerida: “El ingreso mensual de los hogares aumentó tras la intervención (mediana de las diferencias = S/ 60). La prueba de Wilcoxon de rangos con signo fue significativa (\(W^+ = 65\), \(p = 0.002\), \(r = 0.85\)), con un aumento típico estimado de S/ 70 (Hodges-Lehmann). La prueba de los signos llevó a la misma conclusión (\(p = 0.006\)).”

Cuidado con la causalidad. Sin un grupo de control no podemos atribuir el aumento al programa: el ingreso pudo subir por otras razones, como la temporada o la economía local.

2.3.10 Ejercicio 9.1

Con los datos de la evaluación (caso 1, sección 7), calcula a mano \(W^+\), \(E(W^+)\) y \(\mathrm{Var}(W^+)\) con la corrección por empates, y verifica tu resultado con wilcox.test().

3 Sesión 9.2 — Prueba U de Mann-Whitney

3.1 El caso: diferencias salariales por género

Se registró el salario mensual (S/) de 10 hombres y 9 mujeres que ocupan el mismo puesto en una empresa. ¿Existen diferencias salariales por género?

Ahora las muestras son independientes: son personas distintas y no hay emparejamiento.

hombres <- c(1850, 2100, 1720, 2600, 1980, 2300, 1650, 2450, 2050, 3100)
mujeres <- c(1600, 1750, 1500, 1900, 2020, 1680, 1450, 2200, 1580)
n1 <- length(hombres); n2 <- length(mujeres); N <- n1 + n2
c(n1 = n1, n2 = n2, mediana_H = median(hombres), mediana_M = median(mujeres))
#>        n1        n2 mediana_H mediana_M 
#>        10         9      2075      1680

3.2 Idea intuitiva

Juntamos los 19 salarios, los ordenamos y anotamos de qué grupo es cada uno. Si no hubiera diferencia entre grupos, los rangos de hombres y mujeres estarían bien mezclados. Si los hombres ocupan sistemáticamente los rangos altos, hay evidencia de que tienden a ganar más.

3.3 Supuestos e hipótesis

  • Dos muestras independientes entre sí, con observaciones independientes dentro de cada una.
  • Variable al menos ordinal, de distribución continua.

\[H_0: \text{las dos distribuciones son iguales} \;\; \big(P(X > Y) = \tfrac12\big)\] \[H_1: \text{una tiende a dar valores mayores que la otra} \;\; \big(P(X > Y) \neq \tfrac12\big)\]

Importante: Mann-Whitney contrasta si \(P(X > Y) = 1/2\). Solo equivale a comparar medianas si ambas distribuciones tienen la misma forma y difieren solo en su ubicación.

3.4 El estadístico U

  1. Ordenar las \(N = n_1 + n_2\) observaciones juntas y asignar rangos.
  2. \(R_1 =\) suma de los rangos del grupo 1; \(R_2 =\) suma de los rangos del grupo 2.
  3. Calcular \[U_1 = R_1 - \frac{n_1(n_1+1)}{2}, \qquad U_2 = n_1 n_2 - U_1 .\]

Interpretación de \(U_1\) (demostración). \(U_1\) es el número de pares \((X_i, Y_j)\) en los que el valor del grupo 1 supera al del grupo 2: \[U_1 = \#\{(i,j): X_i > Y_j\}.\] Demostración. Ordenemos el grupo 1: \(X_{(1)} < X_{(2)} < \cdots < X_{(n_1)}\). El rango de \(X_{(i)}\) en la muestra combinada es su posición: hay \(i - 1\) valores del grupo 1 por debajo de él, más los valores del grupo 2 menores que él. Por tanto \[\text{rango}(X_{(i)}) = i + \#\{j: Y_j < X_{(i)}\}.\] Sumando sobre \(i = 1, \dots, n_1\): \[R_1 = \sum_{i=1}^{n_1} i + \sum_{i=1}^{n_1} \#\{j: Y_j < X_{(i)}\} = \frac{n_1(n_1+1)}{2} + U_1. \qquad \blacksquare\]

Por eso \(\frac{U_1}{n_1 n_2}\) estima \(P(X > Y)\), la probabilidad de que un hombre elegido al azar gane más que una mujer elegida al azar.

Distribución bajo \(H_0\). Todas las asignaciones de rangos a los grupos son igualmente probables. Se demuestra que \[E(U) = \frac{n_1 n_2}{2}, \qquad \mathrm{Var}(U) = \frac{n_1 n_2 (N+1)}{12} \quad (\text{sin empates}),\] y para muestras grandes \(Z = \dfrac{U - E(U)}{\sqrt{\mathrm{Var}(U)}} \approx N(0,1)\). Para muestras pequeñas y sin empates se usa la distribución exacta (función pwilcox() en R).

3.5 Cálculo paso a paso

# Paso 1: rangos de la muestra combinada
todos <- c(hombres, mujeres)
grupo <- rep(c("Hombre", "Mujer"), c(n1, n2))
rg    <- rank(todos)
tabla_mw <- data.frame(salario = todos, grupo, rango = rg)
tabla_mw[order(tabla_mw$rango), ]
salario grupo rango
17 1450 Mujer 1
13 1500 Mujer 2
19 1580 Mujer 3
11 1600 Mujer 4
7 1650 Hombre 5
16 1680 Mujer 6
3 1720 Hombre 7
12 1750 Mujer 8
1 1850 Hombre 9
14 1900 Mujer 10
5 1980 Hombre 11
15 2020 Mujer 12
9 2050 Hombre 13
2 2100 Hombre 14
18 2200 Mujer 15
6 2300 Hombre 16
8 2450 Hombre 17
4 2600 Hombre 18
10 3100 Hombre 19
# Paso 2: sumas de rangos (comprobación: R1 + R2 = N(N+1)/2)
R1 <- sum(rg[grupo == "Hombre"]); R2 <- sum(rg[grupo == "Mujer"])
c(R1 = R1, R2 = R2, suma = R1 + R2, N_N1_2 = N * (N + 1) / 2)
#>     R1     R2   suma N_N1_2 
#>    129     61    190    190
# Paso 3: estadísticos U (comprobación: U1 + U2 = n1 * n2)
U1 <- R1 - n1 * (n1 + 1) / 2
U2 <- n1 * n2 - U1
c(U1 = U1, U2 = U2, n1_n2 = n1 * n2)
#>    U1    U2 n1_n2 
#>    74    16    90
# Paso 4: verificar la interpretación de U1 contando los pares directamente
sum(outer(hombres, mujeres, ">"))
#> [1] 74

El conteo directo confirma la demostración: en 74 de los 90 pares hombre–mujer, el hombre gana más.

# Paso 5: p-valor exacto bilateral = 2 * P(U <= min(U1, U2))
p_exacto <- 2 * pwilcox(min(U1, U2) , n1, n2)
# Aproximación normal, solo para comparar
EU <- n1 * n2 / 2; VU <- n1 * n2 * (N + 1) / 12
Zu <- (U1 - EU) / sqrt(VU)
c(p_exacto = p_exacto, Z = Zu, p_normal = 2 * pnorm(-abs(Zu)))
#>  p_exacto         Z  p_normal 
#> 0.0172119 2.3678401 0.0178923

Con estos valores: \[U_1 = 129 - \frac{10 \cdot 11}{2} = 74, \qquad E(U) = \frac{90}{2} = 45, \qquad \mathrm{Var}(U) = \frac{90 \cdot 20}{12} = 150, \qquad Z = \frac{74 - 45}{\sqrt{150}} = 2.37 .\]

3.6 Confirmación con la función de R

wilcox.test(hombres, mujeres, alternative = "two.sided", exact = TRUE)
#> 
#>  Wilcoxon rank sum exact test
#> 
#> data:  hombres and mujeres
#> W = 74, p-value = 0.0172
#> alternative hypothesis: true location shift is not equal to 0

En R, el estadístico \(W\) de wilcox.test(x, y) es \(U_1\), la \(U\) del primer grupo.

3.7 Tamaño del efecto y estimación

  • Correlación biserial de rangos: \(r_{rb} = \dfrac{2U_1}{n_1 n_2} - 1 = 2\,\hat P(X>Y) - 1\). Va de \(-1\) a \(1\); el valor 0 indica que no hay diferencia.
  • Desplazamiento de Hodges-Lehmann: mediana de todas las diferencias \(X_i - Y_j\).
c(prob_H_mayor = U1 / (n1 * n2),
  biserial     = 2 * U1 / (n1 * n2) - 1,
  HL           = hl_2m(hombres, mujeres))
#> prob_H_mayor     biserial           HL 
#>     0.822222     0.644444   400.000000
boxplot(list(Hombres = hombres, Mujeres = mujeres), col = c("#cfdcf0", "#f3d9de"),
        ylab = "Salario (S/)", main = "Salario mensual por género")
stripchart(list(hombres, mujeres), vertical = TRUE, method = "jitter", add = TRUE, pch = 19)

3.8 Conclusión e informe

Redacción sugerida: “Los salarios de los hombres (Md = 2075) fueron mayores que los de las mujeres (Md = 1680) en el mismo puesto, \(U = 74\), \(p = 0.017\) (prueba exacta). En el 82 % de los pares hombre–mujer el hombre percibe más (\(r_{rb} = 0.64\), efecto grande), con una diferencia típica estimada de S/ 400 mensuales (Hodges-Lehmann).”

Para discutir: comparar a personas del mismo puesto controla parte de las diferencias, pero no otros factores como la antigüedad, las horas trabajadas o la formación.

3.8.1 Ejercicio 9.2

Agrega una mujer con salario de S/ 3200 y repite el análisis. ¿Cambia mucho \(U\)? ¿Y cambiaría mucho la diferencia de medias? Explica por qué las pruebas de rangos son robustas frente a valores extremos.

4 Sesión 10.1 — Prueba Chi-cuadrado de independencia

4.1 El caso: educación y acceso a servicios de salud

En una encuesta a 360 personas se registró el nivel educativo y si tuvieron acceso a servicios de salud cuando lo necesitaron. ¿El acceso depende del nivel educativo?

tabla <- matrix(c(45, 55, 90, 60, 85, 25), nrow = 3, byrow = TRUE,
                dimnames = list(Educacion = c("Primaria", "Secundaria", "Superior"),
                                Acceso = c("Si", "No")))
addmargins(tabla)
#>             Acceso
#> Educacion     Si  No Sum
#>   Primaria    45  55 100
#>   Secundaria  90  60 150
#>   Superior    85  25 110
#>   Sum        220 140 360

4.2 Idea intuitiva

Si el acceso no dependiera de la educación, la proporción con acceso sería la misma en los tres niveles, igual a la proporción global \(220/360 = 61.1\%\). La prueba compara las frecuencias observadas con las que esperaríamos si hubiera independencia.

4.3 Hipótesis y frecuencias esperadas (demostración)

\[H_0: \text{el acceso es independiente del nivel educativo} \qquad H_1: \text{existe asociación}.\]

Dos eventos \(A\) y \(B\) son independientes si \(P(A \cap B) = P(A)\,P(B)\). Estimando cada probabilidad marginal con su proporción muestral, \(\hat P(\text{fila } i) = f_i/n\) y \(\hat P(\text{columna } j) = c_j/n\), la frecuencia esperada en la celda \((i,j)\) bajo \(H_0\) es

\[E_{ij} = n \cdot \frac{f_i}{n} \cdot \frac{c_j}{n} = \frac{f_i \, c_j}{n} = \frac{(\text{total de la fila } i)(\text{total de la columna } j)}{n}.\]

4.4 El estadístico

\[\chi^2 = \sum_{i=1}^{r} \sum_{j=1}^{c} \frac{(O_{ij} - E_{ij})^2}{E_{ij}} \;\sim\; \chi^2_{(r-1)(c-1)} \quad \text{(aproximadamente, bajo } H_0).\]

  • Cada término mide cuánto se aleja la celda de lo esperado, en relación con lo esperado.
  • Grados de libertad: una vez fijados los totales de filas y columnas, solo \((r-1)(c-1)\) celdas pueden variar libremente; las demás quedan determinadas por los totales.
  • Rechazamos \(H_0\) si \(\chi^2\) es grande: la prueba es siempre de cola derecha.

Supuestos: observaciones independientes y frecuencias esperadas suficientemente grandes (\(E_{ij} \ge 5\) en todas las celdas, o al menos en el 80 % y ninguna menor que 1). Si no se cumplen, usamos la prueba exacta de Fisher.

4.5 Cálculo paso a paso

# Paso 1: totales marginales
f_i <- rowSums(tabla); c_j <- colSums(tabla); n <- sum(tabla)

# Paso 2: frecuencias esperadas E_ij = f_i * c_j / n
E <- outer(f_i, c_j) / n
round(E, 2)
#>               Si    No
#> Primaria   61.11 38.89
#> Secundaria 91.67 58.33
#> Superior   67.22 42.78
all(E >= 5)       # ¿se cumple el supuesto?
#> [1] TRUE

Por ejemplo, \(E_{11} = \dfrac{100 \times 220}{360} = 61.11\): si hubiera independencia, esperaríamos 61 personas con primaria y con acceso, y observamos 45.

# Paso 3: contribución de cada celda y estadístico
contrib <- (tabla - E)^2 / E
round(contrib, 3)
#>             Acceso
#> Educacion       Si    No
#>   Primaria   4.247 6.675
#>   Secundaria 0.030 0.048
#>   Superior   4.702 7.388
chi2 <- sum(contrib)

# Paso 4: grados de libertad, valor crítico y p-valor
gl <- (nrow(tabla) - 1) * (ncol(tabla) - 1)
c(chi2 = chi2, gl = gl, valor_critico = qchisq(0.95, gl),
  p_valor = pchisq(chi2, gl, lower.tail = FALSE))
#>          chi2            gl valor_critico       p_valor 
#>   2.30897e+01   2.00000e+00   5.99146e+00   9.68566e-06

Decisión: \(\chi^2 = 23.09 > 5.99\) (valor crítico con 2 gl), o equivalentemente \(p < 0.001\). Rechazamos la independencia.

curve(dchisq(x, df = 2), from = 0, to = 26, lwd = 2, col = "#1856a0",
      ylab = "Densidad", xlab = expression(chi^2),
      main = "Distribución chi-cuadrado con 2 gl")
abline(v = qchisq(0.95, 2), lty = 2, col = "grey40")
abline(v = chi2, lwd = 2, col = "#80162a")
legend("topright", bty = "n", lty = c(2, 1), col = c("grey40", "#80162a"),
       legend = c("Valor crítico 5.99", "Valor observado 23.09"))

4.6 Confirmación con la función de R

prueba <- chisq.test(tabla, correct = FALSE)
prueba
#> 
#>  Pearson's Chi-squared test
#> 
#> data:  tabla
#> X-squared = 23.09, df = 2, p-value = 9.69e-06

4.7 ¿Dónde está la asociación y qué tan fuerte es?

Residuos estandarizados ajustados. Indican qué celdas se alejan más de lo esperado: \[r_{ij} = \frac{O_{ij} - E_{ij}}{\sqrt{E_{ij}\left(1 - \frac{f_i}{n}\right)\left(1 - \frac{c_j}{n}\right)}} \approx N(0,1).\] Valores con \(|r_{ij}| > 2\) señalan celdas con más casos (si es positivo) o menos casos (si es negativo) de los esperados.

r_aj <- (tabla - E) / sqrt(E * outer(1 - f_i / n, 1 - c_j / n))
round(r_aj, 3)
#>             Acceso
#> Educacion        Si     No
#>   Primaria   -3.889  3.889
#>   Secundaria -0.365  0.365
#>   Superior    4.172 -4.172
round(prueba$stdres, 3)           # R los calcula igual
#>             Acceso
#> Educacion        Si     No
#>   Primaria   -3.889  3.889
#>   Secundaria -0.365  0.365
#>   Superior    4.172 -4.172

V de Cramér. Mide la fuerza de la asociación entre 0 (ninguna) y 1 (perfecta): \[V = \sqrt{\frac{\chi^2}{n\,(k-1)}}, \qquad k = \min(r, c).\]

k <- min(dim(tabla))
c(V_Cramer = sqrt(chi2 / (n * (k - 1))))
#> V_Cramer 
#> 0.253255
round(prop.table(tabla, 1), 3)    # proporciones por fila
#>             Acceso
#> Educacion       Si    No
#>   Primaria   0.450 0.550
#>   Secundaria 0.600 0.400
#>   Superior   0.773 0.227
barplot(prop.table(tabla, 1)[, "Si"], col = c("#80162a", "#1856a0", "#2c7a4b"),
        ylim = c(0, 1), ylab = "Proporción con acceso",
        main = "Acceso a servicios de salud por nivel educativo")
abline(h = sum(tabla[, "Si"]) / n, lty = 2)

Redacción sugerida: “El acceso a servicios de salud se asoció con el nivel educativo, \(\chi^2(2, N = 360) = 23.09\), \(p < 0.001\), \(V = 0.25\). El acceso aumentó de 45 % en primaria a 77 % en educación superior. Los residuos ajustados muestran que la asociación proviene de los extremos: primaria por debajo de lo esperado (\(r = -3.89\)) y superior por encima (\(r = 4.17\)).”

4.8 Tablas pequeñas: prueba exacta de Fisher

En un programa piloto con 20 personas se registró si participaron y si mejoraron:

t2 <- matrix(c(7, 2, 3, 8), 2, byrow = TRUE,
             dimnames = list(Programa = c("Si", "No"), Mejora = c("Si", "No")))
addmargins(t2)
#>         Mejora
#> Programa Si No Sum
#>      Si   7  2   9
#>      No   3  8  11
#>      Sum 10 10  20
outer(rowSums(t2), colSums(t2)) / sum(t2)       # esperadas: todas < 5
#>     Si  No
#> Si 4.5 4.5
#> No 5.5 5.5

Las frecuencias esperadas son menores que 5, así que la aproximación chi-cuadrado no es confiable.

Fundamento de Fisher. Con los totales de filas y columnas fijos, la frecuencia \(a\) de la celda superior izquierda sigue una distribución hipergeométrica bajo \(H_0\): \[P(a) = \frac{\binom{a+b}{a}\binom{c+d}{c}}{\binom{n}{a+c}}.\] El p-valor bilateral suma las probabilidades de todas las tablas tan o menos probables que la observada.

# Valores posibles de a: de 0 a 9 (total de la fila 1); m = 10 mejoran, n = 10 no, k = 9 participan
a_pos <- 0:9
prob  <- dhyper(a_pos, m = 10, n = 10, k = 9)
data.frame(a = a_pos, probabilidad = round(prob, 5))
a probabilidad
0 0.00006
1 0.00268
2 0.03215
3 0.15004
4 0.31508
5 0.31508
6 0.15004
7 0.03215
8 0.00268
9 0.00006
p_fisher <- sum(prob[prob <= prob[a_pos == 7] * (1 + 1e-7)])
c(p_fisher_manual = p_fisher)
#> p_fisher_manual 
#>       0.0697785
fisher.test(t2)$p.value
#> [1] 0.0697785
chisq.test(t2, correct = FALSE)$p.value         # chi-cuadrado (no confiable aquí)
#> [1] 0.0246188

Moraleja: el chi-cuadrado daría \(p = 0.025\) (significativo) y Fisher da \(p = 0.070\) (no significativo). Con muestras pequeñas, la elección de la prueba cambia la conclusión. Por eso siempre se revisan las frecuencias esperadas antes de interpretar.

4.8.1 Ejercicio 10.1

Duplica todas las frecuencias de la tabla t2 y repite ambas pruebas. ¿Qué ocurre con los p-valores? ¿Y con las frecuencias esperadas?

5 Sesión 10.2 — Taller: encuesta de salud pública

5.1 Los datos

Trabajaremos con una encuesta de 240 personas (datos simulados con fines didácticos, con una estructura similar a la de las encuestas de salud). La base viene incluida en este archivo.

# La base viene incluida en este mismo archivo (bloque oculto "base-incluida", al inicio),
# por lo que el notebook funciona sin archivos adicionales.
# Si prefiere leer un CSV desde su computadora, use en su lugar:
#   df <- read.csv(file.choose())
df <- read.csv(text = encuesta_csv)
write.csv(df, "encuesta_salud.csv", row.names = FALSE)   # deja una copia del CSV en la carpeta
str(df)
#> 'data.frame':    240 obs. of  10 variables:
#>  $ id           : int  1 2 3 4 5 6 7 8 9 10 ...
#>  $ sexo         : chr  "Mujer" "Hombre" "Mujer" "Mujer" ...
#>  $ area         : chr  "Rural" "Rural" "Rural" "Urbano" ...
#>  $ edad         : int  22 29 28 38 23 27 69 43 60 21 ...
#>  $ nivel_educ   : chr  "Secundaria" "Superior" "Secundaria" "Secundaria" ...
#>  $ fuma         : chr  "No" "No" "Si" "No" ...
#>  $ actividad_min: int  74 289 92 29 175 250 122 160 34 176 ...
#>  $ imc          : num  26 23.3 23.8 26.3 25.5 28.3 23.6 25 23.3 28.7 ...
#>  $ pas_pre      : num  NA NA NA NA 141 152 NA NA 129 NA ...
#>  $ pas_post     : num  NA NA NA NA 136 149 NA NA 119 NA ...
Variable Tipo Descripción
sexo, area categórica Mujer / Hombre; Urbano / Rural
edad numérica edad en años (18 a 69)
nivel_educ ordinal Primaria / Secundaria / Superior
fuma categórica Si / No
actividad_min numérica minutos de actividad física por semana
imc numérica índice de masa corporal (kg/m²)
pas_pre, pas_post numérica (pareada) presión arterial sistólica antes y después de un programa (solo 25 participantes)
summary(df[, c("edad", "actividad_min", "imc")])
#>       edad      actividad_min         imc      
#>  Min.   :18.0   Min.   :   2.0   Min.   :21.0  
#>  1st Qu.:29.0   1st Qu.:  63.8   1st Qu.:23.8  
#>  Median :43.0   Median : 130.0   Median :25.4  
#>  Mean   :42.9   Mean   : 161.4   Mean   :25.9  
#>  3rd Qu.:56.0   3rd Qu.: 209.2   3rd Qu.:27.3  
#>  Max.   :69.0   Max.   :1392.0   Max.   :39.4
table(df$area); table(df$sexo, df$fuma)
#> 
#>  Rural Urbano 
#>     92    148
#>         
#>           No  Si
#>   Hombre  93  23
#>   Mujer  108  16

Metodología del taller. Para cada pregunta seguimos los mismos pasos: (1) identificar el tipo de variable y de diseño; (2) plantear las hipótesis; (3) elegir y justificar la prueba; (4) ejecutarla; (5) interpretar.

5.2 Paso 1. ¿Es razonable suponer normalidad?

La prueba de Shapiro-Wilk contrasta \(H_0\): los datos provienen de una distribución normal. La complementamos con gráficos, porque con muestras grandes la prueba detecta desviaciones mínimas.

by(df$actividad_min, df$area, function(x)
  c(n = length(x), mediana = median(x), media = mean(x),
    W = unname(shapiro.test(x)$statistic), p = shapiro.test(x)$p.value))
#> df$area: Rural
#>           n     mediana       media           W           p 
#> 9.20000e+01 1.51500e+02 1.99043e+02 7.33247e-01 1.23683e-11 
#> ------------------------------------------------------------ 
#> df$area: Urbano
#>           n     mediana       media           W           p 
#> 1.48000e+02 1.24000e+02 1.38047e+02 8.83791e-01 2.12881e-09
par(mfrow = c(1, 2), mar = c(4, 4, 2.5, 1))
hist(df$actividad_min, breaks = 25, col = "#cfdcf0", border = "white",
     main = "Actividad física (min/sem)", xlab = "minutos")
abline(v = c(mean(df$actividad_min), median(df$actividad_min)), col = c("#80162a", "#1856a0"), lwd = 2)
legend("topright", bty = "n", col = c("#80162a", "#1856a0"), lwd = 2, legend = c("media", "mediana"))
qqnorm(df$actividad_min, pch = 19, cex = .6, main = "Gráfico Q-Q normal"); qqline(df$actividad_min, col = "#80162a", lwd = 2)

Interpretación: la distribución es muy asimétrica a la derecha (la media supera a la mediana y los puntos se alejan de la recta en el Q-Q). Shapiro-Wilk rechaza la normalidad en ambas áreas (\(p < 0.001\)). Usaremos pruebas basadas en rangos.

5.3 Paso 2. ¿Difiere la actividad física entre áreas? (Mann-Whitney)

  • Diseño: dos grupos independientes (rural y urbano); variable numérica asimétrica.
  • \(H_0\): la distribución de la actividad física es igual en ambas áreas; \(H_1\): es distinta.
rur <- df$actividad_min[df$area == "Rural"]; urb <- df$actividad_min[df$area == "Urbano"]
c(n_rural = length(rur), n_urbano = length(urb),
  mediana_rural = median(rur), mediana_urbano = median(urb))
#>        n_rural       n_urbano  mediana_rural mediana_urbano 
#>           92.0          148.0          151.5          124.0
mw <- wilcox.test(rur, urb, exact = FALSE, correct = TRUE)
mw
#> 
#>  Wilcoxon rank sum test with continuity correction
#> 
#> data:  rur and urb
#> W = 7978, p-value = 0.0254
#> alternative hypothesis: true location shift is not equal to 0
U_r <- unname(mw$statistic)
c(prob_rural_mayor = U_r / (length(rur) * length(urb)),
  biserial = 2 * U_r / (length(rur) * length(urb)) - 1,
  HL = hl_2m(rur, urb))
#> prob_rural_mayor         biserial               HL 
#>         0.585892         0.171783        29.000000

Hay empates y las muestras son grandes, así que R usa la aproximación normal (exact = FALSE).

Interpretación: la población rural realiza más actividad física (\(p = 0.025\)), con una diferencia típica de unos 29 minutos semanales. Sin embargo, el efecto es pequeño (\(r_{rb} = 0.17\)): en el 59 % de los pares rural–urbano, la persona rural se ejercita más.

5.4 Paso 3. ¿Está asociado el tabaquismo con el sexo? (Chi-cuadrado)

  • Diseño: dos variables categóricas; tabla \(2 \times 2\).
  • \(H_0\): el tabaquismo es independiente del sexo.
t <- table(df$sexo, df$fuma); addmargins(t)
#>         
#>           No  Si Sum
#>   Hombre  93  23 116
#>   Mujer  108  16 124
#>   Sum    201  39 240
chisq.test(t)$expected                  # todas mayores que 5
#>         
#>              No    Si
#>   Hombre  97.15 18.85
#>   Mujer  103.85 20.15
chisq.test(t)                           # con corrección de Yates (por defecto en 2x2)
#> 
#>  Pearson's Chi-squared test with Yates' continuity correction
#> 
#> data:  t
#> X-squared = 1.633, df = 1, p-value = 0.201
c(sin_correccion = chisq.test(t, correct = FALSE)$p.value, fisher = fisher.test(t)$p.value)
#> sin_correccion         fisher 
#>       0.146197       0.163831
round(prop.table(t, 1), 3)
#>         
#>             No    Si
#>   Hombre 0.802 0.198
#>   Mujer  0.871 0.129

En tablas \(2 \times 2\), R aplica por defecto la corrección de Yates: \(\chi^2 = \sum \frac{(|O - E| - 0.5)^2}{E}\), que hace la prueba más conservadora.

Interpretación: la prevalencia de tabaquismo es 19.8 % en hombres y 12.9 % en mujeres, pero la diferencia no es significativa (\(p = 0.20\)). Atención: no significativo no significa “no hay diferencia”. Con solo 39 fumadores, la prueba tiene poca potencia para detectar diferencias de esta magnitud.

5.5 Paso 4. ¿Redujo el programa la presión arterial? (Wilcoxon pareado)

  • Diseño: mismas personas medidas antes y después, es decir, datos pareados (\(n = 25\)).
  • \(H_0\): la mediana del cambio (post − pre) es 0; \(H_1\): es menor que 0 (la presión bajó).
pa  <- na.omit(df[, c("pas_pre", "pas_post")])
dif <- pa$pas_post - pa$pas_pre
c(n = nrow(pa), mediana_cambio = median(dif), negativos = sum(dif < 0),
  positivos = sum(dif > 0), nulos = sum(dif == 0))
#>              n mediana_cambio      negativos      positivos          nulos 
#>             25             -7             23              2              0
wilcox.test(pa$pas_post, pa$pas_pre, paired = TRUE, alternative = "less",
            exact = FALSE, correct = TRUE)
#> 
#>  Wilcoxon signed rank test with continuity correction
#> 
#> data:  pa$pas_post and pa$pas_pre
#> V = 20.5, p-value = 6.92e-05
#> alternative hypothesis: true location shift is less than 0
c(HL = hl_1m(dif[dif != 0]),
  p_signos = prueba_signos(dif, alternative = "less")$p.value)
#>           HL     p_signos 
#> -7.00000e+00  9.71556e-06

Interpretación: la presión sistólica disminuyó de forma significativa (\(V = 20.5\), \(p < 0.001\)), con una reducción típica de 7 mmHg. La prueba de los signos coincide.

5.6 Paso 5. ¿La mediana del IMC supera 25? (prueba de los signos, una muestra)

  • Un IMC de 25 kg/m² es el umbral del sobrepeso.
  • \(H_0\): \(M = 25\); \(H_1\): \(M > 25\).
c(mediana = median(df$imc), encima = sum(df$imc > 25), debajo = sum(df$imc < 25),
  iguales = sum(df$imc == 25))
#> mediana  encima  debajo iguales 
#>   25.35  129.00  105.00    6.00
prueba_signos(df$imc, m0 = 25, alternative = "greater")
#> 
#>  Exact binomial test
#> 
#> data:  pos and pos + neg
#> number of successes = 129, number of trials = 234, p-value = 0.0663
#> alternative hypothesis: true probability of success is greater than 0.5
#> 95 percent confidence interval:
#>  0.495405 1.000000
#> sample estimates:
#> probability of success 
#>               0.551282

Interpretación: aunque la mediana muestral (25.35) supera ligeramente a 25, la evidencia no es suficiente al 5 % (\(p = 0.066\)).

5.7 Resumen del taller

data.frame(
  Pregunta = c("Normalidad (actividad física)", "Actividad: rural vs urbano",
               "Tabaquismo y sexo", "Presión pre/post", "Mediana del IMC > 25"),
  Prueba   = c("Shapiro-Wilk", "Mann-Whitney", "Chi-cuadrado (Yates)",
               "Wilcoxon pareado", "Signos"),
  p_valor  = signif(c(shapiro.test(rur)$p.value, mw$p.value, chisq.test(t)$p.value,
                      wilcox.test(pa$pas_post, pa$pas_pre, paired = TRUE, alternative = "less",
                                  exact = FALSE)$p.value,
                      prueba_signos(df$imc, 25, "greater")$p.value), 3),
  Decision = c("No normal", "Diferencia (efecto pequeño)", "No se rechaza H0",
               "La presión bajó", "No se rechaza H0"))
Pregunta Prueba p_valor Decision
Normalidad (actividad física) Shapiro-Wilk 0.000000 No normal
Actividad: rural vs urbano Mann-Whitney 0.025400 Diferencia (efecto pequeño)
Tabaquismo y sexo Chi-cuadrado (Yates) 0.201000 No se rechaza H0
Presión pre/post Wilcoxon pareado 0.000069 La presión bajó
Mediana del IMC > 25 Signos 0.066300 No se rechaza H0
par(mfrow = c(1, 3), mar = c(4, 4, 2.5, 1))
boxplot(actividad_min ~ area, data = df, col = c("#f3d9de", "#cfdcf0"),
        main = "Actividad física (min/sem)", xlab = "")
barplot(prop.table(t, 1)[, "Si"], col = c("#1856a0", "#80162a"), main = "Prevalencia de tabaquismo")
hist(dif, breaks = 10, col = "#2c7a4b", border = "white", main = "Cambio en PAS (post - pre)", xlab = "mmHg")
abline(v = 0, lwd = 2)

5.7.1 Ejercicio 10.2

Usando la base, contrasta si el IMC difiere entre fumadores y no fumadores, y si el nivel educativo se asocia con el área. Para cada caso, justifica la prueba elegida.

6 Sesión 11.1 — Limitaciones en muestras pequeñas

6.1 El p-valor mínimo alcanzable

Una prueba exacta solo puede tomar un número finito de valores. En la prueba de los signos (y en la de Wilcoxon), el resultado más extremo posible es que todos los signos sean iguales, y su probabilidad bilateral es \[p_{\min} = 2 \cdot \left(\tfrac12\right)^n .\] Con \(n \le 5\) se tiene \(p_{\min} \ge 0.0625\): ningún resultado puede ser significativo al 5 %, por grande que sea el efecto.

data.frame(n = 3:8, p_min_bilateral = round(2 * 0.5^(3:8), 4))
n p_min_bilateral
3 0.2500
4 0.1250
5 0.0625
6 0.0312
7 0.0156
8 0.0078
# Mann-Whitney con n1 = n2 = m: p mínimo = 2 / C(2m, m)
sapply(2:4, function(m) c(n_por_grupo = m, p_min = round(2 / choose(2 * m, m), 4)))
#>               [,1] [,2]   [,3]
#> n_por_grupo 2.0000  3.0 4.0000
#> p_min       0.3333  0.1 0.0286

Consecuencia ética: diseñar un estudio con 5 pares y concluir “el programa no tiene efecto” es un error metodológico, no un hallazgo.

6.2 Potencia por simulación

La potencia es la probabilidad de rechazar \(H_0\) cuando es falsa. La estimamos simulando muchas muestras con un efecto real (desplazamiento de 0.5) y contando cuántas veces se rechaza.

set.seed(123)
potencia <- function(n, rdist, delta = 0.5, B = 4000) {
  rech <- replicate(B, {
    x <- rdist(n) + delta                       # muestra con efecto real
    c(t = t.test(x)$p.value < 0.05,
      w = suppressWarnings(wilcox.test(x)$p.value) < 0.05)
  })
  rowMeans(rech)                                # proporción de rechazos
}
res <- expand.grid(n = c(8, 15, 30), dist = c("Normal", "t con 3 gl"), stringsAsFactors = FALSE)
pot <- t(mapply(function(n, dist)
  potencia(n, if (dist == "Normal") rnorm else function(k) rt(k, df = 3)), res$n, res$dist))
cbind(res, round(pot, 3))
n dist t w
8 Normal 0.230 0.185
15 Normal 0.446 0.422
30 Normal 0.756 0.743
8 t con 3 gl 0.156 0.152
15 t con 3 gl 0.252 0.286
30 t con 3 gl 0.415 0.536

Lectura:

  • Con datos normales, Wilcoxon pierde muy poca potencia frente a \(t\) (su eficiencia relativa es \(3/\pi \approx 0.955\)).
  • Con datos de colas pesadas (\(t\) con 3 gl, parecidos a ingresos con valores extremos), Wilcoxon es más potente que \(t\).
  • Con \(n = 8\), la potencia es menor que 25 %: tres de cada cuatro efectos reales pasarían inadvertidos.

6.3 Preguntas para el debate

  1. El caso 9.1 tiene 12 hogares. ¿Qué podría afirmar el municipio en su informe y qué no?
  2. En el taller, el tabaquismo no se asoció con el sexo. ¿Debe concluirse que no hay diferencia?
  3. Con datos de solo 6 comunidades, ¿es ético publicar un ranking de comunidades?
  4. ¿Cuándo es preferible un análisis descriptivo honesto a una prueba de hipótesis?

7 Sesiones 12.1 y 12.2 — Evaluación parcial y solucionario

Para cada caso: (a) plantea \(H_0\) y \(H_1\); (b) justifica la prueba; (c) ejecútala; (d) reporta el estadístico, el p-valor y el tamaño del efecto; (e) interpreta en el contexto.

7.1 Caso 1: digitalización de citas en centros de salud

Tiempo de espera promedio (minutos) en 10 centros, antes y después de implementar citas digitales.

antes   <- c(35, 42, 28, 50, 38, 45, 33, 40, 55, 30)
despues <- c(30, 35, 29, 41, 30, 38, 30, 36, 44, 27)
dd <- despues - antes
data.frame(centro = 1:10, antes, despues, dif = dd, rango = rank(abs(dd)))
centro antes despues dif rango
1 35 30 -5 5.0
2 42 35 -7 6.5
3 28 29 1 1.0
4 50 41 -9 9.0
5 38 30 -8 8.0
6 45 38 -7 6.5
7 33 30 -3 2.5
8 40 36 -4 4.0
9 55 44 -11 10.0
10 30 27 -3 2.5

Solución. Datos pareados; \(H_0\): la mediana del cambio es 0; \(H_1\): el tiempo disminuyó.

# Prueba de los signos: 9 negativos y 1 positivo -> P(B >= 9 negativos) con n = 10
c(negativos = sum(dd < 0), positivos = sum(dd > 0),
  p_signos = prueba_signos(dd, alternative = "less")$p.value)
#> negativos positivos  p_signos 
#> 9.0000000 1.0000000 0.0107422
# Wilcoxon: el único positivo (+1) tiene el rango 1, así que W+ = 1
wilcox.test(despues, antes, paired = TRUE, alternative = "less", exact = FALSE, correct = TRUE)
#> 
#>  Wilcoxon signed rank test with continuity correction
#> 
#> data:  despues and antes
#> V = 1, p-value = 0.00398
#> alternative hypothesis: true location shift is less than 0
c(HL = hl_1m(dd))
#>   HL 
#> -5.5

Conclusión: el tiempo de espera se redujo de forma significativa (signos \(p = 0.011\); Wilcoxon \(W^+ = 1\), \(p = 0.004\)). La reducción típica es de unos 5.5 minutos por centro.

7.2 Caso 2: gasto en salud según tenencia de seguro

con_seguro <- c(120, 85, 60, 150, 95, 70, 110)
sin_seguro <- c(180, 140, 210, 160, 125, 240, 175, 130)
w2 <- wilcox.test(sin_seguro, con_seguro, alternative = "greater", exact = TRUE)
w2
#> 
#>  Wilcoxon rank sum exact test
#> 
#> data:  sin_seguro and con_seguro
#> W = 53, p-value = 0.00109
#> alternative hypothesis: true location shift is greater than 0
c(biserial = 2 * unname(w2$statistic) / (7 * 8) - 1, HL = hl_2m(sin_seguro, con_seguro))
#>  biserial        HL 
#>  0.892857 67.500000

Solución. Dos grupos independientes y muestras pequeñas con gasto asimétrico, así que no podemos verificar la normalidad: usamos Mann-Whitney. Los hogares sin seguro gastan significativamente más (\(U = 53\) de 56 pares posibles, \(p = 0.001\)), con un efecto muy grande (\(r_{rb} = 0.89\)) y una diferencia típica de S/ 67.5 mensuales.

7.3 Caso 3: vacunación completa por región natural

vac <- matrix(c(120, 30, 95, 55, 60, 40), 3, byrow = TRUE,
              dimnames = list(Region = c("Costa", "Sierra", "Selva"),
                              Vacunacion = c("Completa", "Incompleta")))
c3 <- chisq.test(vac, correct = FALSE); c3
#> 
#>  Pearson's Chi-squared test
#> 
#> data:  vac
#> X-squared = 14.45, df = 2, p-value = 0.000729
round(c3$expected, 2)                       # todas > 5: supuesto cumplido
#>         Vacunacion
#> Region   Completa Incompleta
#>   Costa    103.12      46.88
#>   Sierra   103.12      46.88
#>   Selva     68.75      31.25
round(c3$stdres, 2)
#>         Vacunacion
#> Region   Completa Incompleta
#>   Costa      3.76      -3.76
#>   Sierra    -1.81       1.81
#>   Selva     -2.18       2.18
c(V = unname(sqrt(c3$statistic / sum(vac))))
#>        V 
#> 0.190056
round(prop.table(vac, 1), 3)
#>         Vacunacion
#> Region   Completa Incompleta
#>   Costa     0.800      0.200
#>   Sierra    0.633      0.367
#>   Selva     0.600      0.400

Solución. La vacunación completa depende de la región (\(\chi^2 = 14.45\), gl = 2, \(p < 0.001\)), con una asociación débil a moderada (\(V = 0.19\)). La Costa (80 %) supera a la Sierra (63 %) y a la Selva (60 %). Recomendación: priorizar las campañas de vacunación en la Sierra y la Selva.

7.4 Errores frecuentes en la evaluación

  1. Tratar datos pareados como independientes (usar Mann-Whitney en el caso 1).
  2. No descartar las diferencias nulas o no considerar los empates.
  3. Confundir el \(W\) de R con \(U_2\): verifica siempre que \(U_1 + U_2 = n_1 n_2\).
  4. Aplicar chi-cuadrado a porcentajes en lugar de conteos.
  5. Reportar solo “se rechaza \(H_0\)”, sin la dirección, el tamaño del efecto ni el contexto.
  6. Concluir causalidad a partir de un diseño antes/después sin grupo de control.

8 Resumen de la unidad

8.1 Fórmulas principales

Prueba Estadístico Distribución bajo \(H_0\) Tamaño del efecto
Signos \(B = \#\{D_i > 0\}\) \(\text{Bin}(n^*, 1/2)\) proporción de signos +
Wilcoxon (signo) \(W^+ = \sum\) rangos de \(D_i > 0\) \(E = \frac{n(n+1)}{4}\), \(V = \frac{n(n+1)(2n+1)}{24}\) \(r = Z/\sqrt{n}\)
Mann-Whitney \(U_1 = R_1 - \frac{n_1(n_1+1)}{2}\) \(E = \frac{n_1 n_2}{2}\), \(V = \frac{n_1 n_2 (N+1)}{12}\) \(r_{rb} = \frac{2U_1}{n_1 n_2} - 1\)
Chi-cuadrado \(\sum \frac{(O - E)^2}{E}\), \(E_{ij} = \frac{f_i c_j}{n}\) \(\chi^2_{(r-1)(c-1)}\) \(V = \sqrt{\frac{\chi^2}{n(k-1)}}\)
Fisher celda \(a\) de la tabla \(2\times2\) hipergeométrica odds ratio

8.2 ¿Qué prueba uso?

Situación Prueba Función de R
Mediana de una muestra, o datos pareados, sin suponer simetría Signos binom.test()
Una muestra o pares, distribución simétrica Wilcoxon de rangos con signo wilcox.test(x, y, paired = TRUE)
Dos muestras independientes Mann-Whitney wilcox.test(x, y)
Dos variables categóricas, esperadas \(\ge 5\) Chi-cuadrado chisq.test(tabla)
Dos variables categóricas, esperadas \(< 5\) Fisher exacta fisher.test(tabla)

8.3 Plantilla para redactar resultados

“Se aplicó la prueba [nombre] porque [tipo de datos y diseño; supuesto que no se cumple]. Se obtuvo [estadístico] = [valor], $p = $ [valor], con un tamaño del efecto de [valor] ([pequeño / mediano / grande]). Esto indica que [conclusión en el contexto]. Limitaciones: [tamaño de muestra, diseño, generalización].”

Referencias

  • Agresti, A. (2019). An Introduction to Categorical Data Analysis (3.ª ed.), cap. 2. Wiley.
  • Conover, W. J. (1999). Practical Nonparametric Statistics (3.ª ed.), cap. 5. Wiley.
  • Hollander, M., Wolfe, D. A. y Chicken, E. (2014). Nonparametric Statistical Methods (3.ª ed.), cap. 3. Wiley.
  • Siegel, S. y Castellan, N. J. (1988). Nonparametric Statistics for the Behavioral Sciences (2.ª ed.). McGraw-Hill.
  • Wasserstein, R. L. y Lazar, N. A. (2016). The ASA Statement on p-Values. The American Statistician, 70(2), 129–133.
  • R Core Team (2024). R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing.