Al finalizar este tutorial, el estudiante será capaz de:
aov() en R.Imagina que somos investigadores probando la eficacia de dos nuevos fármacos (A y B) para reducir el dolor, comparados con un Placebo (Control).
Medimos el nivel de dolor de 15 pacientes (5 por grupo) 1 hora después del tratamiento, en una escala de 0 (sin dolor) a 20 (dolor máximo).
Nuestra pregunta: ¿Existen diferencias significativas en el nivel de dolor promedio entre los tres grupos?
Datos:
[16, 17, 15, 16, 16][14, 13, 15, 14, 14][12, 11, 13, 12, 12]ANOVA se basa en comparar la “Señal” (qué tan diferentes son las medias entre los grupos) con el “Ruido” (qué tanta variabilidad “natural” hay dentro de los grupos).
\[F = \frac{\text{Señal}}{\text{Ruido}} = \frac{\text{Variabilidad ENTRE grupos}}{\text{Variabilidad DENTRO de grupos}} = \frac{MS_B}{MS_W}\]
Primero, calculemos las medias, varianzas y tamaños de muestra de nuestros datos.
# Definir los datos
g1_control <- c(16, 17, 15, 16, 16)
g2_farm_A <- c(14, 13, 15, 14, 14)
g3_farm_B <- c(12, 11, 13, 12, 12)
# Parámetros
k <- 3 # Número de grupos
n1 <- length(g1_control); n2 <- length(g2_farm_A); n3 <- length(g3_farm_B)
N <- n1 + n2 + n3 # Tamaño total de muestra (15)
# Medias de grupo (x_barra_i)
m1 <- mean(g1_control) # 16
m2 <- mean(g2_farm_A) # 14
m3 <- mean(g3_farm_B) # 12
# Varianzas de grupo (s_i^2)
v1 <- var(g1_control) # 0.5
v2 <- var(g2_farm_A) # 0.5
v3 <- var(g3_farm_B) # 0.5
# Media Global (x_barra_global)
todos_los_datos <- c(g1_control, g2_farm_A, g3_farm_B)
m_global <- mean(todos_los_datos) # 14
# Imprimir resultados
cat(sprintf("Media Global (Gran Media): %.2f\n", m_global))
## Media Global (Gran Media): 14.00
cat(sprintf("Grupo 1 (Control): n=%.0f, Media=%.2f, Varianza=%.2f\n", n1, m1, v1))
## Grupo 1 (Control): n=5, Media=16.00, Varianza=0.50
cat(sprintf("Grupo 2 (Fármaco A): n=%.0f, Media=%.2f, Varianza=%.2f\n", n2, m2, v2))
## Grupo 2 (Fármaco A): n=5, Media=14.00, Varianza=0.50
cat(sprintf("Grupo 3 (Fármaco B): n=%.0f, Media=%.2f, Varianza=%.2f\n", n3, m3, v3))
## Grupo 3 (Fármaco B): n=5, Media=12.00, Varianza=0.50
Nota: Elegimos datos “limpios” con varianzas iguales (0.5) para facilitar la pedagogía.
\(MS_B\) mide qué tan lejos están
las medias de cada grupo (m1, m2,
m3) de la media global (m_global).
MSB = (Suma de Cuadrados ENTRE) / (grados de libertad
ENTRE)
\(MS_B = \frac{\sum_{i=1}^{k} n_i
(\bar{x}_i - \bar{x})^2}{k-1}\)
1. Suma de Cuadrados ENTRE (\(SS_B\)):
\(SS_B = n_1(\bar{x}_1 - \bar{x})^2 + n_2(\bar{x}_2 - \bar{x})^2 + n_3(\bar{x}_3 - \bar{x})^2\) \(SS_B = 5 \cdot (16 - 14)^2 + 5 \cdot (14 - 14)^2 + 5 \cdot (12 - 14)^2\) \(SS_B = 5 \cdot (2)^2 + 5 \cdot (0)^2 + 5 \cdot (-2)^2\) \(SS_B = 5 \cdot 4 + 0 + 5 \cdot 4\) \(SS_B = 20 + 0 + 20 = 40\)
2. Grados de Libertad ENTRE (\(gl_B\)):
\(gl_B = k - 1 = 3 - 1 = 2\)
3. Cuadrado Medio ENTRE (\(MS_B\)):
\(MS_B = SS_B / gl_B = 40 / 2 = 20\)
Nuestra “Señal” (\(MS_B\)) es 20.
\(MS_W\) mide la variabilidad promedio dentro de los grupos. Es nuestra estimación del “ruido” aleatorio, o la varianza agrupada.
MSW = (Suma de Cuadrados DENTRO) / (grados de libertad
DENTRO)
\(MS_W = \frac{\sum_{i=1}^{k} (n_i
- 1) s_i^2}{N - k}\)
1. Suma de Cuadrados DENTRO (\(SS_W\)):
\(SS_W = (n_1 - 1)s_1^2 + (n_2 - 1)s_2^2 + (n_3 - 1)s_3^2\) \(SS_W = (5 - 1) \cdot 0.5 + (5 - 1) \cdot 0.5 + (5 - 1) \cdot 0.5\) \(SS_W = (4 \cdot 0.5) + (4 \cdot 0.5) + (4 \cdot 0.5)\) \(SS_W = 2 + 2 + 2 = 6\)
2. Grados de Libertad DENTRO (\(gl_W\)):
\(gl_W = N - k = 15 - 3 = 12\)
3. Cuadrado Medio DENTRO (\(MS_W\)):
\(MS_W = SS_W / gl_W = 6 / 12 = 0.5\)
Nuestro “Ruido” (\(MS_W\)) es 0.5.
Interpretación rápida: El \(MS_W\) es 0.5, que es exactamente la varianza que teníamos dentro de cada grupo. ¡Tiene sentido! Es el promedio ponderado de las varianzas internas.
Ahora, comparamos la Señal con el Ruido.
Fobs = MSB / MSW
\(F_{obs} = 20 / 0.5 = 40\)
Nuestro estadístico F observado es 40.
Nuestro \(F_{obs}\) de 40 parece grande, pero… ¿es “lo suficientemente grande” como para ser estadísticamente significativo?
Necesitamos encontrar el valor en la distribución F que deja un 5% del área a la derecha, usando nuestros grados de libertad:
Método 1: “Buscar en la Tabla” (Conceptual) Buscaríamos en una tabla F de \(\alpha=0.05\) la intersección de la columna \(df1=2\) y la fila \(df2=12\).
Método 2: Usando R (Preciso) Usamos la función
qf() (Quantile Function de F).
# qf(p, df1, df2, lower.tail = FALSE)
# p = alfa, df1 = gl_B, df2 = gl_W
alfa <- 0.05
gl_B <- 2
gl_W <- 12
f_critico <- qf(alfa, gl_B, gl_W, lower.tail = FALSE)
cat(sprintf("El valor F crítico (F_crit) con (2, 12) gl y alfa=0.05 es: %.4f\n", f_critico))
## El valor F crítico (F_crit) con (2, 12) gl y alfa=0.05 es: 3.8853
Nuestro \(F_{crit}\) es 3.8853.
Regla de Decisión: Si \(F_{obs} > F_{crit}\), rechazamos \(H_0\).
Comparación: * \(F_{obs} = 40\) * \(F_{crit} = 3.8853\)
\(40 > 3.8853\)
Conclusión: Dado que nuestro estadístico F observado (40) es mucho mayor que el valor F crítico (3.8853), rechazamos la hipótesis nula (\(H_0\)).
Interpretación: Existe evidencia estadística significativa (con \(\alpha = 0.05\)) para concluir que hay una diferencia en el nivel de dolor promedio entre al menos dos de los grupos de tratamiento. Los tratamientos (Placebo, Fármaco A, Fármaco B) no tienen el mismo efecto.
Ahora, hagamos que R haga todo el trabajo en segundos usando
aov() (Analysis of Variance).
R funciona mejor con datos en formato “largo” (tidy format).
# 1. Crear los vectores
# (Asegúrate de haber corrido el chunk "datos_basicos" o vuelve a definirlos)
g1_control <- c(14, 15, 16, 17, 18)
g2_farm_A <- c(12, 13, 14, 15, 16)
g3_farm_B <- c(10, 11, 12, 13, 14)
puntuacion_dolor <- c(g1_control, g2_farm_A, g3_farm_B)
grupo_tratamiento <- factor(c(rep("Control", 5),
rep("Farmaco_A", 5),
rep("Farmaco_B", 5)))
# 2. Combinar en un Data Frame
df_anova <- data.frame(Grupo = grupo_tratamiento,
Dolor = puntuacion_dolor)
# 3. Inspeccionar el data frame
cat("Data Frame para el análisis:\n")
## Data Frame para el análisis:
print(df_anova)
## Grupo Dolor
## 1 Control 14
## 2 Control 15
## 3 Control 16
## 4 Control 17
## 5 Control 18
## 6 Farmaco_A 12
## 7 Farmaco_A 13
## 8 Farmaco_A 14
## 9 Farmaco_A 15
## 10 Farmaco_A 16
## 11 Farmaco_B 10
## 12 Farmaco_B 11
## 13 Farmaco_B 12
## 14 Farmaco_B 13
## 15 Farmaco_B 14
Un boxplot (diagrama de cajas) es la mejor forma de ver
los datos de un ANOVA.
boxplot(Dolor ~ Grupo, data = df_anova,
main = "Nivel de Dolor por Grupo de Tratamiento",
xlab = "Grupo",
ylab = "Puntuación de Dolor (0-20)",
col = c("salmon", "lightblue", "lightgreen"))
Visualmente, las medias (líneas gruesas) se ven muy diferentes, y las
cajas (dispersión interna) son pequeñas. Esto predice un F grande.
Observemos la tabla generada por
summary(modelo_anova_r):
| Df | Sum Sq | Mean Sq | F value | Pr(>F) | |
|---|---|---|---|---|---|
| Grupo | 2 | 40 | 20 | 40 | 4.97e-07 *** |
| Residuals | 12 | 6 | 0.5 |
¡Comparemos con nuestros cálculos manuales!
Df (gl): 2 (¡Correcto!)Sum Sq (\(SS_B\)): 40
(¡Correcto!)Mean Sq (\(MS_B\)): 20
(¡Correcto!)Df (gl): 12 (¡Correcto!)Sum Sq (\(SS_W\)): 6
(¡Correcto!)Mean Sq (\(MS_W\)):
0.5 (¡Correcto!)F value (\(F_{obs}\)):
40 (¡Correcto!)R nos da un valor extra: Pr(>F) o valor
p.
4.97e-07 (o 0.000000497).
Este valor es mucho menor que nuestro \(\alpha\) de 0.05.aov(formula, data) y
summary() realizan el análisis completo y nos entregan la
tabla ANOVA.# Pregunta de Comprobación
(Diseñada según los criterios de alta calidad)
Objetivo evaluado: Interpretación conceptual del Estadístico F.
Enunciado: Un investigador realiza un ANOVA para comparar 4 dietas (k=4) y obtiene un Estadístico F = 0.90. Asumiendo que sus cálculos son correctos, ¿cuál es la interpretación conceptual más precisa de este resultado?
A) La variabilidad explicada por las diferencias entre las dietas (la “Señal”) es menor que la variabilidad aleatoria dentro de cada dieta (el “Ruido”). B) Hay una diferencia estadísticamente significativa entre las 4 dietas, ya que F está cerca de 1. C) El investigador cometió un error, ya que el estadístico F no puede ser menor que 1. D) La varianza promedio dentro de los grupos (\(MS_W\)) es 0.90.
. . . Respuesta Correcta: A Justificación: El estadístico \(F = MS_B / MS_W\). Para que F sea menor que 1 (como 0.90), el denominador (\(MS_W\), Ruido) debe ser más grande que el numerador (\(MS_B\), Señal). Esto significa que hay más “ruido” aleatorio que “señal” (diferencias entre grupos). Distractores: B) Es incorrecto; un F cercano o menor a 1 casi nunca es significativo (implica \(H_0\) es verdadera). C) Es un error común; F puede ser menor que 1 si el ruido es mayor que la señal. D) Es incorrecto; 0.90 es el ratio* F, no el \(MS_W\).