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.
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).
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) \]
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}} \]
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.
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.
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:
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:
Para contrastar si existe correlación significativa:
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 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
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
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
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
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). \]
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\).
Valores típicos:
# 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