Comparar dos grupos: t-test y Wilcoxon

r
estadistica
El test más usado de toda la estadística. Welch como default, Student vs Welch, una-muestra vs dos-muestras vs pareados, y cuándo Wilcoxon es la alternativa correcta.

La pregunta: ¿son distintos?

El t-test responde la pregunta más básica de la estadística inferencial: ¿las medias de dos grupos son significativamente distintas?. Es el test que se usa más veces de las que se justifica, pero también el que más vale la pena dominar bien.

R base lo expone como t.test(). Casi todo el matiz está en sus argumentos.

El caso de dos muestras

# Largo del pétalo en dos especies de Iris
setosa     <- iris$Petal.Length[iris$Species == "setosa"]
versicolor <- iris$Petal.Length[iris$Species == "versicolor"]

t.test(setosa, versicolor)

Salida:

        Welch Two Sample t-test

data:  setosa and versicolor
t = -39.493, df = 62.14, p-value < 2.2e-16
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -2.939618 -2.656382
sample estimates:
mean of x mean of y
    1.462     4.260

Información clave:

  • t: el estadístico.
  • df: grados de libertad (en Welch son fraccionarios, diferente al Student clásico).
  • p-value: probabilidad de observar esta diferencia o mayor, asumiendo H₀ (que las medias son iguales).
  • IC 95 %: rango plausible para la diferencia de medias. Información mucho más útil que el p-value solo.
  • sample estimates: las medias de cada grupo.

Una mejor forma de invocarlo, usando la fórmula:

t.test(Petal.Length ~ Species,
       data = iris,
       subset = Species %in% c("setosa", "versicolor"))

La sintaxis y ~ grupo es la forma idiomática en R para “comparar y entre los niveles de grupo”.

Welch vs Student: qué es el default y por qué

t.test() usa por defecto el test de Welch, no el de Student clásico. La diferencia:

  • Student asume que las dos muestras tienen la misma varianza.
  • Welch no lo asume, ajusta los grados de libertad para acomodar varianzas distintas.

Por qué Welch como default: si las varianzas resultan ser iguales, Welch da resultados prácticamente idénticos a Student. Si son distintas, Student puede dar p-values muy engañosos, pero Welch sigue siendo válido. Welch es estrictamente más robusto.

Para usar Student (raramente recomendado):

t.test(Petal.Length ~ Species, data = iris, var.equal = TRUE,
       subset = Species %in% c("setosa", "versicolor"))

Si en un paper viejo ves var.equal = TRUE, ahora sabes qué significa. En código nuevo, déjalo en el default.

Una muestra: comparar con un valor

A veces quieres comparar una sola muestra contra un valor de referencia (¿la altura media de esta población es 170 cm?):

alturas <- c(168, 172, 165, 178, 170, 169, 174)
t.test(alturas, mu = 170)

mu = 170 es la hipótesis nula. El test responde “¿hay evidencia para rechazar que la media es 170?”.

Datos pareados

Si tus dos muestras vienen de los mismos individuos medidos en dos momentos (antes/después de un tratamiento), o pareados por algún diseño (gemelos, casos-controles emparejados), el test pareado es el correcto:

antes   <- c(120, 135, 142, 128, 150)
despues <- c(115, 130, 138, 122, 148)

t.test(antes, despues, paired = TRUE)

Conceptualmente, el test pareado convierte el problema en un test de una muestra sobre las diferencias individuales. Es mucho más potente que tratar antes y después como muestras independientes, porque elimina la variabilidad entre individuos.

Trampa común: olvidar paired = TRUE cuando los datos son pareados. El p-value resultante es más alto del que debería. Pierdes poder estadístico.

Wilcoxon: cuando los supuestos no se cumplen

Si los datos son visiblemente no normales (QQ-plot curvo, n muy pequeño, datos ordinales), Wilcoxon es la alternativa no-paramétrica.

wilcox.test(Petal.Length ~ Species,
            data = iris,
            subset = Species %in% c("setosa", "versicolor"))

Dos variantes:

  • Mann-Whitney U: para muestras independientes (lo que da wilcox.test() por defecto).
  • Wilcoxon signed-rank: para muestras pareadas. Se activa con paired = TRUE.

Wilcoxon compara medianas y formas de las distribuciones, no medias. Si reportas Wilcoxon, no digas “el grupo A tiene mayor media que B (Wilcoxon p < 0.05)”, di “distribuciones diferentes” o “la mediana de A es mayor que la de B”.

Reportar bien: p-value + intervalo + tamaño de efecto

Un p-value solo dice “hay evidencia de diferencia”. No dice cuánta. Para reportar de forma defendible, incluye tres cosas:

  1. Estadístico y p-value: la inferencia formal.
  2. Intervalo de confianza: el rango plausible para la diferencia real.
  3. Tamaño de efecto: magnitud estandarizada.

Para t-test, el tamaño de efecto típico es Cohen’s d:

install.packages("effectsize")
library(effectsize)

cohens_d(Petal.Length ~ Species,
         data = iris,
         subset = Species %in% c("setosa", "versicolor"))

Interpretación heurística de d (Cohen 1988):

  • 0.2, efecto pequeño
  • 0.5, efecto mediano
  • 0.8, efecto grande

Reportar tamaño de efecto evita el problema clásico de “con n grande, todo es estadísticamente significativo pero nada importa”.

Trampas habituales

  • t-test con datos visiblemente no normales y n pequeño. El CLT no salva. Usa Wilcoxon o bootstrap.
  • No usar paired = TRUE con datos pareados. El test independiente subestima el poder, especialmente con correlación intra-individuo alta.
  • Reportar p < 0.05 sin IC ni tamaño de efecto. Revisores serios lo penalizan. Da los tres.
  • Asumir Student por costumbre. Welch es el default por buena razón. Solo usa Student si tienes prueba teórica de varianzas iguales (raro).

En la siguiente entrega

Has aprendido a comparar dos grupos. Si tienes tres o más, no puedes hacer t-tests pareados (los p-values pierden sentido por comparaciones múltiples). La solución se llama ANOVA. Es el siguiente tutorial.