Introducción

La prueba U de Mann-Whitney (también conocida como prueba de rangos de Wilcoxon para muestras independientes) es una prueba no paramétrica que se utiliza para comparar dos muestras independientes y determinar si provienen de la misma población.

Es útil cuando no se cumple el supuesto de normalidad requerido en la prueba t para muestras independientes.

Hipótesis

Se plantean las siguientes hipótesis:

\[ H_0: \; F_X = F_Y \]

(donde \(F_X\) y \(F_Y\) son las funciones de distribución de las dos poblaciones).

\[ H_1: \; F_X \neq F_Y \]

(lo que implica que las distribuciones difieren en ubicación).

Estadístico de prueba

Supongamos dos muestras independientes:

Se combinan todas las observaciones y se ordenan de menor a mayor, asignando rangos. Sea \(R_i\) el rango de la observación \(X_i\).

El estadístico \(U\) se define como:

\[ U_1 = n_1 n_2 + \frac{n_1 (n_1 + 1)}{2} - \sum_{i=1}^{n_1} R_i \]

\[ U_2 = n_1 n_2 - U_1 \]

El estadístico final es:

\[ U = \min(U_1, U_2) \]

Distribución bajo \(H_0\)

Cuando \(n_1\) y \(n_2\) son grandes (\(n_1, n_2 > 10\)), se aproxima por una distribución normal:

\[ Z = \frac{U - \mu_U}{\sigma_U} \]

donde

\[ \mu_U = \frac{n_1 n_2}{2}, \quad \sigma_U = \sqrt{\frac{n_1 n_2 (n_1 + n_2 + 1)}{12}} \]

Conclusión

Esta prueba es robusta frente a distribuciones no normales y se usa ampliamente en estudios comparativos de dos grupos independientes.

## ------------------------------------------------------------
## Prueba U de Mann-Whitney (Wilcoxon rank-sum) en R
## - Usa wilcox.test para el p-valor (exacto o asintótico según el caso)
## - Recupera U a partir del estadístico W de R
## - Calcula Z con corrección por empates
## - Informa Hodges–Lehmann y delta de Cliff
## ------------------------------------------------------------

mann_whitney_u <- function(x, y,
                           alternative = c("two.sided", "less", "greater"),
                           exact = NULL,      # deja que R decida (exacto si n pequeño y sin empates)
                           correct = TRUE) {  # corrección de continuidad en Z
  alternative <- match.arg(alternative)
  x <- as.numeric(x); y <- as.numeric(y)
  x <- x[is.finite(x)]; y <- y[is.finite(y)]
  n1 <- length(x); n2 <- length(y); N <- n1 + n2
  if (n1 < 1 || n2 < 1) stop("Ambos grupos deben tener al menos una observación.")

  ## 1) Prueba con base R
  wt <- stats::wilcox.test(x, y, alternative = alternative,
                           exact = exact, correct = correct, paired = FALSE)

  ## 2) Recuperar U a partir de W (rank-sum del primer grupo que pasa a wilcox.test)
  ## R reporta 'W' = suma de rangos del primer vector (x). Relación:
  ## U1 = W - n1*(n1 + 1)/2 ; U2 = n1*n2 - U1 ; U = min(U1, U2)
  W  <- unname(wt$statistic)
  U1 <- W - n1*(n1 + 1)/2
  U2 <- n1*n2 - U1
  U  <- min(U1, U2)

  ## 3) Z asintótico con corrección por empates (varianza de suma de rangos)
  ## Ranks con empates:
  all_vals <- c(x, y)
  r <- rank(all_vals, ties.method = "average")

  ## Contar tamaños de grupos de empates t_k
  ## (frecuencia de cada valor idéntico dentro del total combinado)
  tab <- table(all_vals)
  tk  <- as.numeric(tab[tab > 1])  # solo empates (>1)
  tie_term <- if (length(tk)) sum(tk^3 - tk) else 0

  mu_W  <- n1 * (N + 1) / 2
  var_W <- n1 * n2 / 12 * ( (N + 1) - tie_term / (N * (N - 1)) )

  if (var_W <= 0) {
    Z <- NA_real_
  } else {
    cc <- if (correct) 0.5 else 0
    ## Dirección de la corrección según alternativa
    adj <- switch(alternative,
                  "two.sided" = 0,  # se maneja con |.| + cc abajo
                  "greater"   = -cc,
                  "less"      =  cc)
    if (alternative == "two.sided") {
      Z <- (abs(W - mu_W) - cc) / sqrt(var_W)
      Z <- sign(W - mu_W) * Z  # signo informativo
    } else {
      Z <- (W - mu_W + adj) / sqrt(var_W)
    }
  }

  ## 4) Estimador de Hodges–Lehmann (mediana de Xi - Yj)
  hl <- stats::median(outer(x, y, `-`))

  ## 5) Tamaño de efecto: delta de Cliff
  ## delta = P(X>Y) - P(X<Y)
  S <- sign(outer(x, y, `-`))
  cliff_delta <- sum(S) / (n1 * n2)

  list(
    method         = "Mann–Whitney U (Wilcoxon rank-sum)",
    alternative    = alternative,
    n1 = n1, n2 = n2,
    W = W,
    U = U,
    p_value = wt$p.value,
    Z = Z,
    mu_W = mu_W,
    var_W = var_W,
    hodges_lehmann = hl,
    cliffs_delta = cliff_delta
  )
}

## ---------------------- EJEMPLOS ---------------------------

set.seed(123)

## Ejemplo 1: sin diferencia (misma distribución)
x1 <- rnorm(15, mean = 0, sd = 1)
y1 <- rnorm(18, mean = 0, sd = 1)
res1 <- mann_whitney_u(x1, y1, alternative = "two.sided")
print(res1)
## $method
## [1] "Mann–Whitney U (Wilcoxon rank-sum)"
## 
## $alternative
## [1] "two.sided"
## 
## $n1
## [1] 15
## 
## $n2
## [1] 18
## 
## $W
## [1] 153
## 
## $U
## [1] 33
## 
## $p_value
## [1] 0.5319669
## 
## $Z
## [1] -3.66974
## 
## $mu_W
## [1] 255
## 
## $var_W
## [1] 765
## 
## $hodges_lehmann
## [1] 0.3340539
## 
## $cliffs_delta
## [1] 0.1333333
## Ejemplo 2: diferencias en ubicación (grupo X mayor)
x2 <- rnorm(20, mean = 0.9, sd = 1)
y2 <- rnorm(22, mean = 0.0, sd = 1)
res2 <- mann_whitney_u(x2, y2, alternative = "greater")
print(res2)
## $method
## [1] "Mann–Whitney U (Wilcoxon rank-sum)"
## 
## $alternative
## [1] "greater"
## 
## $n1
## [1] 20
## 
## $n2
## [1] 22
## 
## $W
## [1] 346
## 
## $U
## [1] 136
## 
## $p_value
## [1] 0.0005693621
## 
## $Z
## [1] -2.128074
## 
## $mu_W
## [1] 430
## 
## $var_W
## [1] 1576.667
## 
## $hodges_lehmann
## [1] 1.008134
## 
## $cliffs_delta
## [1] 0.5727273
## Ejemplo 3: con empates (valores discretos)
x3 <- sample(1:5, 12, replace = TRUE)
y3 <- sample(1:5, 14, replace = TRUE)
x3
##  [1] 3 1 3 5 2 3 2 5 5 3 4 4
y3
##  [1] 4 5 3 1 2 1 2 5 3 4 4 1 4 1
x4 <- sample(1:5, 12, replace = TRUE)
y4 <- sample(4:10, 14, replace = TRUE)
x4
##  [1] 3 4 3 5 4 4 4 1 2 3 4 3
y4
##  [1]  4 10  9  8  8  5  6  8  9  9  4  7  5  7
res3 <- mann_whitney_u(x4, y4, alternative = "two.sided")
## Warning in wilcox.test.default(x, y, alternative = alternative, exact = exact,
## : cannot compute exact p-value with ties
print(res3)
## $method
## [1] "Mann–Whitney U (Wilcoxon rank-sum)"
## 
## $alternative
## [1] "two.sided"
## 
## $n1
## [1] 12
## 
## $n2
## [1] 14
## 
## $W
## [1] 8
## 
## $U
## [1] -70
## 
## $p_value
## [1] 8.256544e-05
## 
## $Z
## [1] -8.004016
## 
## $mu_W
## [1] 162
## 
## $var_W
## [1] 367.7908
## 
## $hodges_lehmann
## [1] -4
## 
## $cliffs_delta
## [1] -0.9047619
## Nota:
## - Si los tamaños son pequeños y no hay empates, R puede usar p-valor exacto.
## - Para forzar asintótico, usa exact = FALSE en mann_whitney_u(...).
## - Para forzar exacto (si es posible), usa exact = TRUE.

Correlación no paramétrica

Definición

El coeficiente de correlación de Spearman (\(\rho_s\)) mide la asociación monótona entre dos variables.
Se basa en los rangos de los datos en lugar de sus valores originales.

Fórmula General

Si tenemos \(n\) observaciones \((X_i, Y_i)\), se reemplazan por sus rangos \(R(X_i)\) y \(R(Y_i)\).
La correlación de Spearman se define como:

\[ \rho_s = 1 - \frac{6 \sum_{i=1}^{n} d_i^2}{n(n^2 - 1)} \]

donde:

  • \(d_i = R(X_i) - R(Y_i)\) es la diferencia entre los rangos de cada par.
  • \(n\) es el número de observaciones.

Relación con la correlación de Pearson

Otra forma de expresarlo es calcular la correlación de Pearson entre los rangos:

\[ \rho_s = \frac{\operatorname{Cov}(R_X, R_Y)}{\sigma_{R_X} \, \sigma_{R_Y}} \]

donde:

  • \(R_X\) y \(R_Y\) son los rangos de las variables \(X\) e \(Y\).
  • \(\sigma_{R_X}\) y \(\sigma_{R_Y}\) son las desviaciones estándar de los rangos.

Hipótesis de Prueba

Para contrastar si existe correlación significativa:

  • Hipótesis nula (\(H_0\)): \(\rho_s = 0\) (no hay correlación monótona).
  • Hipótesis alternativa (\(H_1\)): \(\rho_s \neq 0\).

Cuando \(n > 10\), el estadístico puede aproximarse por:

\[ t = \rho_s \sqrt{\frac{n-2}{1-\rho_s^2}} \sim t_{n-2} \]

Ejemplo en R

# Ejemplo de cálculo en R
x <- c(10, 20, 30, 40, 50)
y <- c(12, 25, 33, 47, 52)

cor(x, y, method = "spearman")
## [1] 1
x<-rnorm(1000,0,1)
y<-5*x+rnorm(1000,0,1)
plot(x,y)

cor.test(x,y)
## 
##  Pearson's product-moment correlation
## 
## data:  x and y
## t = 158.98, df = 998, p-value < 2.2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.9783164 0.9830435
## sample estimates:
##       cor 
## 0.9808237
cor.test(x,y,method = "spearman")
## 
##  Spearman's rank correlation rho
## 
## data:  x and y
## S = 3687988, p-value < 2.2e-16
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
##      rho 
## 0.977872
x<-rnorm(1000,0,1)
y<-x**2
plot(x,y)

cor(x,y)
## [1] -0.01553435
x<-rnorm(100,0,1)
y<-x**7
plot(x,y)

cor(x,y)
## [1] 0.4388221
cor.test(x,y,method = "spearman")
## 
##  Spearman's rank correlation rho
## 
## data:  x and y
## S = 0, p-value < 2.2e-16
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
## rho 
##   1

Definición y equivalencia con Pearson en rangos

Sea \((X_i,Y_i)_{i=1}^n\) un m.a.s., y denote \(R_i=\operatorname{rank}(X_i)\), \(S_i=\operatorname{rank}(Y_i)\). El coeficiente de Spearman se define como la correlación de Pearson entre los rangos:

\[ \rho_s \;=\; \frac{\operatorname{Cov}(R,S)}{\sigma_R\,\sigma_S}. \]

Bajo ausencia de empates (ranks \(1,\dots,n\)), se tiene \(\bar R=\bar S=(n+1)/2\) y \(\sigma_R^2=\sigma_S^2=(n^2-1)/12\). Además, para \(d_i=R_i-S_i\),

\[ \frac{1}{n}\sum_{i=1}^n R_iS_i - \bar R\,\bar S = \sigma_R^2 - \frac{1}{2n}\sum_{i=1}^n d_i^2. \]

Por tanto,

\[ \rho_s \;=\; \frac{\sigma_R^2 - \frac{1}{2n}\sum d_i^2}{\sigma_R\,\sigma_S} = 1 - \frac{\sum d_i^2}{2n\,\sigma_R^2} = 1 - \frac{6\sum_{i=1}^n d_i^2}{n(n^2-1)}. \]

Esto prueba que Pearson aplicado a los rangos coincide con la fórmula clásica de Spearman sin empates. (Con empates, se mantiene la definición \(\rho_s=\text{cor}(R,S)\), pero ya no vale la forma cerrada con \(\sum d_i^2\).) :contentReferenceoaicite:0

2. Inferencia: de permutaciones a la aproximación t

2.1. Idea de prueba asintótica (bajo \(H_0\): independencia y márgenes continuos)

Bajo \(H_0\), los pares de rangos \((R_i,S_i)\) son equiprobables sobre todas las permutaciones; \(\rho_s\) es una estadística de rangos que puede representarse como (o está estrechamente ligada a) un U-estadístico de orden 2. Por resultados clásicos de teoría asintótica de U-estadísticos (Hoeffding), \[ \sqrt{n}\,\rho_s \;\xrightarrow{d}\; \mathcal N\!\big(0,\;\sigma^2\big), \] para cierta varianza \(\sigma^2\) que depende únicamente de la copula bajo la hipótesis nula (y que es conocida/obtenible en la literatura). En particular, bajo independencia \(\rho_s\) es asintóticamente normal de media 0. :contentReferenceoaicite:1

2.2. Por qué funciona el estadístico tipo t

En la práctica se usa el transformado de Pearson aplicado a \(r_s\equiv\hat\rho_s\) (correlación muestral de los rangos): \[ t \;=\; r_s\,\sqrt{\frac{n-2}{1-r_s^2}}. \] Este estadístico tiene distribución t con \(n-2\) gl aproximada bajo \(H_0\). Intuición: - Al ser \(r_s\) una correlación de Pearson (pero sobre rangos), se hereda el mismo estadístico funcional que linealiza \(r\) y conduce a \(t\). - Como \(r_s\) es asintóticamente normal por 2.1, el delta method aplicado a \(g(r)=r/\sqrt{1-r^2}\) entrega que \(t\) es asintóticamente normal estándar. - La t de Student con \(n-2\) gl converge a \(\mathcal N(0,1)\) cuando \(n\to\infty\); de ahí que la aproximación t para Spearman sea razonable (y ampliamente usada) para \(n\gtrsim 10\). Para \(n\) pequeños o con muchos empates, prefiera el test por permutaciones exactas. :contentReferenceoaicite:2

Nota: Existen también aproximaciones vía transformación de Fisher \(z=\sqrt{\tfrac{n-3}{1.06}}\,\operatorname{arctanh}(r_s)\), que lleva a un estadístico aproximadamente normal estándar bajo \(H_0\). :contentReferenceoaicite:3

3. Código R de ejemplo

set.seed(1)
x <- rnorm(30); y <- rnorm(30)         # H0: independencia
rs  <- cor(x, y, method = "spearman")  # = Pearson sobre rangos

# Estadístico t aproximado y p-valor bilateral
tstat <- rs * sqrt((length(x)-2)/(1 - rs^2))
pval  <- 2*pt(-abs(tstat), df = length(x)-2)
c(r_s = rs, t = tstat, p_value = pval)
##        r_s          t    p_value 
## 0.01535039 0.08123620 0.93583202

Alternativas psicométricas

Alpha de Cronbach

Definición

El alfa de Cronbach (\(\alpha\)) mide la confiabilidad o consistencia interna de un conjunto de ítems que pretenden medir un mismo constructo.

Sea un cuestionario con \(k\) ítems, cada uno con varianza \(\sigma_i^2\).
Si \(X_T = \sum_{i=1}^k X_i\) es la puntuación total, su varianza es \(\sigma_T^2\).

El alfa de Cronbach se define como:

\[ \alpha = \frac{k}{k-1}\left( 1 - \frac{\sum_{i=1}^k \sigma_i^2}{\sigma_T^2} \right). \]

2. Forma matricial

Si \(\mathbf{X} = (X_1, X_2, \dots, X_k)\) y \(\Sigma\) es la matriz de covarianzas, entonces:

\[ \alpha = \frac{k}{k-1}\left(1 - \frac{\operatorname{tr}(\Sigma)}{\mathbf{1}^\top \Sigma \mathbf{1}} \right), \]

donde \(\operatorname{tr}(\Sigma)\) es la traza (suma de varianzas) y
\(\mathbf{1}^\top \Sigma \mathbf{1} = \sigma_T^2\).

3. Interpretación

Valores típicos:

  • \(\alpha < 0.6\): confiabilidad baja.
  • \(0.6 \leq \alpha < 0.7\): aceptable.
  • \(0.7 \leq \alpha < 0.9\): buena.
  • \(\alpha \geq 0.9\): excelente (pero puede indicar redundancia excesiva).

4. Ejemplo en R

# Paquete necesario
if(!require(psych)) install.packages("psych")
## Cargando paquete requerido: psych
library(psych)

# Simulación: 5 ítems, 50 individuos
set.seed(123)
datos <- data.frame(
  item1 = rnorm(50, 10, 3),
  item2 = rnorm(50, 11, 3),
  item3 = rnorm(50, 9, 3),
  item4 = rnorm(50, 10, 3),
  item5 = rnorm(50, 12, 3)
)

# Calcular alfa de Cronbach
alpha(datos)
## Number of categories should be increased  in order to count frequencies.
## Warning in alpha(datos): Some items were negatively correlated with the first principal component and probably 
## should be reversed.  
## To do this, run the function again with the 'check.keys=TRUE' option
## Some items ( item1 item2 ) were negatively correlated with the first principal component and 
## probably should be reversed.  
## To do this, run the function again with the 'check.keys=TRUE' option
## Warning in sqrt(Vtc): Se han producido NaNs
## 
## Reliability analysis   
## Call: alpha(x = datos)
## 
##   raw_alpha std.alpha G6(smc) average_r  S/N  ase mean  sd median_r
##      -0.41     -0.42   -0.26    -0.063 -0.3 0.31   10 1.1   -0.081
## 
##     95% confidence boundaries 
##          lower alpha upper
## Feldt    -1.14 -0.41  0.12
## Duhachek -1.03 -0.41  0.21
## 
##  Reliability if an item is dropped:
##       raw_alpha std.alpha G6(smc) average_r   S/N alpha se  var.r  med.r
## item1     -0.22     -0.23  -0.111    -0.048 -0.18     0.28 0.0184 -0.084
## item2     -0.11     -0.11  -0.036    -0.026 -0.10     0.26 0.0197 -0.023
## item3     -0.39     -0.40  -0.216    -0.077 -0.28     0.32 0.0214 -0.125
## item4     -0.49     -0.50  -0.308    -0.091 -0.33     0.34 0.0082 -0.084
## item5     -0.38     -0.39  -0.245    -0.075 -0.28     0.32 0.0065 -0.079
## 
##  Item statistics 
##        n raw.r std.r r.cor r.drop mean  sd
## item1 50  0.33  0.34   NaN -0.183 10.1 2.8
## item2 50  0.25  0.27   NaN -0.249 11.4 2.7
## item3 50  0.46  0.43   NaN -0.097  8.2 3.0
## item4 50  0.47  0.47   NaN -0.046 10.1 2.8
## item5 50  0.43  0.42   NaN -0.102 12.0 2.8