Estructura del análisis: La base wage1 se divide en dos grupos independientes de igual tamaño (\(n_A = n_B = 256\)). Se realizan tres bloques de análisis:

  1. Estadísticas descriptivas por grupo
  2. Comparación de medias — prueba \(t\) individual por variable y prueba \(T^2\) de Hotelling multivariante
  3. Comparación de varianzas — prueba \(F\) clásica por variable

Variables analizadas: wage, educ, tenure, exper


1 Preparación de Datos

1.1 Carga de librerías

# Instalar si es necesario:
# install.packages(c("wooldridge", "ICSNP", "ellipse"))

library(wooldridge)
library(ICSNP)
library(ellipse)

1.2 Partición de la base en dos grupos

data("wage1")

# Seleccionar las 4 variables y eliminar valores faltantes
datos <- na.omit(wage1[, c("wage", "educ", "tenure", "exper")])
cat("Total de observaciones disponibles:", nrow(datos), "\n\n")
## Total de observaciones disponibles: 526
# Tamaños de grupo definidos en el ejercicio
n1 <- 256
n2 <- 256

# Grupo A: primeras 256 observaciones
# Grupo B: siguientes 256 observaciones
XA <- as.matrix(datos[1:n1, ])
XB <- as.matrix(datos[(n1 + 1):(n1 + n2), ])

cat("Grupo A — filas:", nrow(XA), "| columnas:", ncol(XA), "\n")
## Grupo A — filas: 256 | columnas: 4
cat("Grupo B — filas:", nrow(XB), "| columnas:", ncol(XB), "\n")
## Grupo B — filas: 256 | columnas: 4

2 Estadísticas Descriptivas por Grupo

vars <- c("wage", "educ", "tenure", "exper")

desc_A <- data.frame(
  Variable  = vars,
  Media     = round(colMeans(XA), 4),
  Varianza  = round(apply(XA, 2, var), 4),
  Desv.Est  = round(apply(XA, 2, sd), 4),
  Minimo    = round(apply(XA, 2, min), 4),
  Maximo    = round(apply(XA, 2, max), 4)
)

desc_B <- data.frame(
  Variable  = vars,
  Media     = round(colMeans(XB), 4),
  Varianza  = round(apply(XB, 2, var), 4),
  Desv.Est  = round(apply(XB, 2, sd), 4),
  Minimo    = round(apply(XB, 2, min), 4),
  Maximo    = round(apply(XB, 2, max), 4)
)

cat("=== Estadisticas descriptivas — Grupo A ===\n")
## === Estadisticas descriptivas — Grupo A ===
print(desc_A, row.names = FALSE)
##  Variable   Media Varianza Desv.Est Minimo Maximo
##      wage  6.3124  16.5334   4.0661   0.53  24.98
##      educ 12.7695   6.2408   2.4982   2.00  18.00
##    tenure  4.9492  46.4249   6.8136   0.00  39.00
##     exper 16.0234 170.0387  13.0399   1.00  48.00
cat("\n=== Estadisticas descriptivas — Grupo B ===\n")
## 
## === Estadisticas descriptivas — Grupo B ===
print(desc_B, row.names = FALSE)
##  Variable   Media Varianza Desv.Est Minimo Maximo
##      wage  5.4402  10.3548   3.2179    1.5     20
##      educ 12.3320   9.0854   3.0142    0.0     18
##    tenure  5.3047  58.8715   7.6728    0.0     44
##     exper 18.2188 198.7049  14.0963    1.0     51

2.1 Boxplots comparativos

par(mfrow = c(1, 4), mar = c(4, 4, 3, 1))

colores <- c("#3b82f6", "#f97316")

for (v in vars) {
  boxplot(
    XA[, v], XB[, v],
    names  = c("Grupo A", "Grupo B"),
    col    = colores,
    main   = v,
    ylab   = v,
    border = c("#1d4ed8", "#c2410c"),
    notch  = FALSE
  )
  grid(col = "#e2e8f0")
}

par(mfrow = c(1, 1))

3 Comparación de Medias

3.1 Prueba \(t\) de Student — Variable por variable

Para cada variable se contrasta: \[H_0: \mu_{A,j} = \mu_{B,j} \qquad \text{vs} \qquad H_1: \mu_{A,j} \neq \mu_{B,j}\] Se aplica la prueba \(t\) de dos muestras independientes con \(\alpha = 0.05\).

alpha <- 0.05

resultados_t <- data.frame(
  Variable   = character(),
  Media_A    = numeric(),
  Media_B    = numeric(),
  Diferencia = numeric(),
  t_stat     = numeric(),
  gl         = numeric(),
  p_valor    = numeric(),
  Decision   = character(),
  stringsAsFactors = FALSE
)

for (v in vars) {
  tt <- t.test(XA[, v], XB[, v], var.equal = FALSE)

  resultados_t <- rbind(resultados_t, data.frame(
    Variable   = v,
    Media_A    = round(mean(XA[, v]), 4),
    Media_B    = round(mean(XB[, v]), 4),
    Diferencia = round(mean(XA[, v]) - mean(XB[, v]), 4),
    t_stat     = round(tt$statistic, 4),
    gl         = round(tt$parameter, 2),
    p_valor    = round(tt$p.value, 6),
    Decision   = ifelse(tt$p.value < alpha,
                        "Rechazar H0", "No rechazar H0"),
    stringsAsFactors = FALSE
  ))
}

print(resultados_t, row.names = FALSE)
##  Variable Media_A Media_B Diferencia  t_stat     gl  p_valor       Decision
##      wage  6.3124  5.4402     0.8723  2.6915 484.42 0.007360    Rechazar H0
##      educ 12.7695 12.3320     0.4375  1.7881 493.02 0.074381 No rechazar H0
##    tenure  4.9492  5.3047    -0.3555 -0.5543 502.97 0.579646 No rechazar H0
##     exper 16.0234 18.2188    -2.1953 -1.8292 506.94 0.067961 No rechazar H0

3.1.1 Visualización de diferencias de medias

dif <- colMeans(XA) - colMeans(XB)

# Intervalos de confianza de la diferencia
ic_inf <- numeric(length(vars))
ic_sup <- numeric(length(vars))

for (i in seq_along(vars)) {
  tt <- t.test(XA[, vars[i]], XB[, vars[i]], var.equal = FALSE)
  ic_inf[i] <- tt$conf.int[1]
  ic_sup[i] <- tt$conf.int[2]
}

colores_dif <- ifelse(resultados_t$p_valor < alpha, "#dc2626", "#16a34a")

bp <- barplot(
  dif,
  names.arg = vars,
  col       = colores_dif,
  border    = NA,
  main      = "Diferencia de Medias por Variable (A - B)\nRojo = diferencia significativa  |  Verde = no significativa",
  ylab      = "Diferencia de medias",
  ylim      = c(min(ic_inf) * 1.3, max(ic_sup) * 1.3)
)

arrows(bp, ic_inf, bp, ic_sup,
       angle = 90, code = 3, length = 0.08, col = "#1e293b", lwd = 1.5)
abline(h = 0, lty = 2, col = "#64748b", lwd = 1.5)
grid(col = "#e2e8f0")

Las barras rojas indican variables donde se rechaza \(H_0\) (diferencia significativa entre grupos). Las barras verdes indican que no hay evidencia de diferencia. Las líneas verticales representan los intervalos de confianza al 95%.


3.2 Prueba \(T^2\) de Hotelling — Contraste Multivariante

La prueba de Hotelling evalúa simultáneamente si los vectores de medias son iguales: \[H_0: \boldsymbol{\mu}_A = \boldsymbol{\mu}_B \qquad \text{vs} \qquad H_1: \boldsymbol{\mu}_A \neq \boldsymbol{\mu}_B\]

3.2.1 Prueba automática (referencia)

HotellingsT2(XA, XB)
## 
##  Hotelling's two sample T2-test
## 
## data:  XA and XB
## T.2 = 3.102, df1 = 4, df2 = 507, p-value = 0.01537
## alternative hypothesis: true location difference is not equal to c(0,0,0,0)

3.2.2 Cálculo manual paso a paso

p <- ncol(XA)

# Vectores de medias
xbarA <- colMeans(XA)
xbarB <- colMeans(XB)
d     <- xbarA - xbarB

# Matrices de covarianza
SA <- cov(XA)
SB <- cov(XB)

# Matriz pooled
Sp     <- ((n1 - 1) * SA + (n2 - 1) * SB) / (n1 + n2 - 2)
Sp_inv <- solve(Sp)

# Estadístico T²
factor_escala <- 1 / (1/n1 + 1/n2)
T2   <- as.numeric(factor_escala * t(d) %*% Sp_inv %*% d)

# Transformación a F
gl1  <- p
gl2  <- n1 + n2 - p - 1
Fval <- (n1 + n2 - p - 1) / (p * (n1 + n2 - 2)) * T2
pval_T2 <- pf(Fval, df1 = gl1, df2 = gl2, lower.tail = FALSE)

decision_T2 <- ifelse(pval_T2 < alpha, "Se rechaza H0", "No se rechaza H0")

cat("--------------------------------------------------\n")
## --------------------------------------------------
cat(sprintf("  Estadistico T^2  = %.4f\n", T2))
##   Estadistico T^2  = 12.4815
cat(sprintf("  Estadistico F    = %.4f\n", Fval))
##   Estadistico F    = 3.1020
cat(sprintf("  df1 = %d  |  df2 = %d\n", gl1, gl2))
##   df1 = 4  |  df2 = 507
cat(sprintf("  p-valor          = %.6f\n", pval_T2))
##   p-valor          = 0.015368
cat(sprintf("  alpha            = %.2f\n", alpha))
##   alpha            = 0.05
cat("--------------------------------------------------\n")
## --------------------------------------------------
cat(sprintf("  Decision: %s\n", decision_T2))
##   Decision: Se rechaza H0
cat("--------------------------------------------------\n")
## --------------------------------------------------

3.2.3 Región de confianza al 95% (wage vs educ)

ell <- ellipse(Sp[1:2, 1:2], centre = d[1:2], level = 0.95)

plot(ell, type = "l", lwd = 2, col = "#2563eb",
     main = "Region de confianza al 95%\n(wage vs educ)",
     xlab = expression(mu[A] - mu[B] ~ "(wage)"),
     ylab = expression(mu[A] - mu[B] ~ "(educ)"),
     panel.first = grid(col = "#e2e8f0"))

points(d[1], d[2], pch = 19, col = "#dc2626", cex = 1.8)
points(0, 0,    pch = 4,  col = "#16a34a", cex = 2.2, lwd = 2.5)
abline(h = 0, v = 0, lty = 2, col = "#94a3b8")

legend("topright",
  legend = c("Diferencia observada", "Origen H0"),
  pch = c(19, 4), col = c("#dc2626", "#16a34a"),
  pt.lwd = 2, bty = "n")


4 Comparación de Varianzas

4.1 Prueba \(F\) clásica — Variable por variable

Para cada variable se contrasta la igualdad de varianzas poblacionales: \[H_0: \sigma^2_{A,j} = \sigma^2_{B,j} \qquad \text{vs} \qquad H_1: \sigma^2_{A,j} \neq \sigma^2_{B,j}\] El estadístico es \(F = S^2_A / S^2_B \sim F_{n_1-1,\, n_2-1}\) bajo \(H_0\).

resultados_F <- data.frame(
  Variable    = character(),
  Varianza_A  = numeric(),
  Varianza_B  = numeric(),
  Razon_F     = numeric(),
  gl1         = numeric(),
  gl2         = numeric(),
  p_valor     = numeric(),
  Decision    = character(),
  stringsAsFactors = FALSE
)

for (v in vars) {
  vA  <- var(XA[, v])
  vB  <- var(XB[, v])
  Fst <- vA / vB
  gl_1 <- n1 - 1
  gl_2 <- n2 - 1

  # p-valor bilateral
  pv <- 2 * min(
    pf(Fst, df1 = gl_1, df2 = gl_2, lower.tail = TRUE),
    pf(Fst, df1 = gl_1, df2 = gl_2, lower.tail = FALSE)
  )

  resultados_F <- rbind(resultados_F, data.frame(
    Variable   = v,
    Varianza_A = round(vA, 4),
    Varianza_B = round(vB, 4),
    Razon_F    = round(Fst, 4),
    gl1        = gl_1,
    gl2        = gl_2,
    p_valor    = round(pv, 6),
    Decision   = ifelse(pv < alpha, "Rechazar H0", "No rechazar H0"),
    stringsAsFactors = FALSE
  ))
}

print(resultados_F, row.names = FALSE)
##  Variable Varianza_A Varianza_B Razon_F gl1 gl2  p_valor       Decision
##      wage    16.5334    10.3548  1.5967 255 255 0.000203    Rechazar H0
##      educ     6.2408     9.0854  0.6869 255 255 0.002818    Rechazar H0
##    tenure    46.4249    58.8715  0.7886 255 255 0.058440 No rechazar H0
##     exper   170.0387   198.7049  0.8557 255 255 0.214208 No rechazar H0

4.1.1 Visualización de razones de varianza

Fvals_plot <- resultados_F$Razon_F
nombres    <- resultados_F$Variable
col_F      <- ifelse(resultados_F$p_valor < alpha, "#dc2626", "#16a34a")

# Valor crítico F bilateral
F_crit_sup <- qf(1 - alpha/2, df1 = n1 - 1, df2 = n2 - 1)
F_crit_inf <- qf(alpha/2,     df1 = n1 - 1, df2 = n2 - 1)

bp2 <- barplot(
  Fvals_plot,
  names.arg = nombres,
  col       = col_F,
  border    = NA,
  main      = "Razón de Varianzas F = S²A / S²B por Variable\nRojo = diferencia significativa  |  Verde = varianzas iguales",
  ylab      = "F = S²A / S²B",
  ylim      = c(0, max(Fvals_plot) * 1.3)
)

abline(h = F_crit_sup, lty = 2, col = "#f97316", lwd = 2)
abline(h = F_crit_inf, lty = 2, col = "#f97316", lwd = 2)
abline(h = 1,          lty = 3, col = "#64748b", lwd = 1.5)
grid(col = "#e2e8f0")

legend("topright",
  legend = c(
    paste0("F crítico sup = ", round(F_crit_sup, 3)),
    paste0("F crítico inf = ", round(F_crit_inf, 3)),
    "F = 1 (varianzas iguales)"
  ),
  lty = c(2, 2, 3),
  col = c("#f97316", "#f97316", "#64748b"),
  bty = "n", cex = 0.85
)

Las barras rojas señalan variables donde se rechaza la igualdad de varianzas. Las líneas naranjas punteadas marcan los valores críticos \(F_{\alpha/2}\) y \(F_{1-\alpha/2}\). Si la barra supera la línea superior o queda por debajo de la inferior, se rechaza \(H_0\).


5 Resumen General

## ======================================================
##           RESUMEN GENERAL DEL ANÁLISIS
##           Grupo A vs Grupo B — wage1
## ======================================================
##   Variables : wage, educ, tenure, exper
##   n_A = 256   |   n_B = 256   |   p = 4
## ── PRUEBA T DE STUDENT (medias univariadas) ─────────
##   wage     | t =  2.6915 | p = 0.007360 | Rechazar H0
##   educ     | t =  1.7881 | p = 0.074381 | No rechazar H0
##   tenure   | t = -0.5543 | p = 0.579646 | No rechazar H0
##   exper    | t = -1.8292 | p = 0.067961 | No rechazar H0
## 
## ── T² DE HOTELLING (medias multivariadas) ───────────
##   T² = 12.4815 | F = 3.1020 | p = 0.015368 | Se rechaza H0
## 
## ── PRUEBA F (varianzas univariadas) ─────────────────
##   wage     | F =  1.5967 | p = 0.000203 | Rechazar H0
##   educ     | F =  0.6869 | p = 0.002818 | Rechazar H0
##   tenure   | F =  0.7886 | p = 0.058440 | No rechazar H0
##   exper    | F =  0.8557 | p = 0.214208 | No rechazar H0
## 
## ======================================================
##   alpha = 0.05 en todos los contrastes
## ======================================================

6 Conclusiones

## 1. COMPARACION DE MEDIAS (prueba t individual)
##    ─────────────────────────────────────────────
##    [!] wage   : medias significativamente diferentes (A=6.312 vs B=5.440, p=0.00736)
##    [=] educ   : sin evidencia de diferencia en medias (A=12.770 vs B=12.332, p=0.07438)
##    [=] tenure : sin evidencia de diferencia en medias (A=4.949 vs B=5.305, p=0.57965)
##    [=] exper  : sin evidencia de diferencia en medias (A=16.023 vs B=18.219, p=0.06796)
## 
## 2. COMPARACION MULTIVARIANTE (T² de Hotelling)
##    ─────────────────────────────────────────────
##    [!] Se RECHAZA H0: los vectores de medias son
##        significativamente diferentes (p = 0.015368)
## 
## 3. COMPARACION DE VARIANZAS (prueba F)
##    ─────────────────────────────────────────────
##    [!] wage   : varianzas significativamente diferentes (F=1.5967, p=0.00020)
##    [!] educ   : varianzas significativamente diferentes (F=0.6869, p=0.00282)
##    [=] tenure : sin evidencia de diferencia en varianzas (F=0.7886, p=0.05844)
##    [=] exper  : sin evidencia de diferencia en varianzas (F=0.8557, p=0.21421)