Pregunta de investigación. ¿Existen diferencias en el rendimiento (t/ha) de cuatro variedades de aceitunas de mesa cultivadas bajo un diseño completamente al azar con distinto número de repeticiones?

Diseño: un factor fijo (variedad), cuatro tratamientos y 24 unidades experimentales. Se adopta un nivel de significación de \(\alpha=0.05\).

1 Base de datos y diseño experimental

datos <- data.frame(
  Tratamiento = factor(c(rep('Sevillana',6), rep('Ascolana',7),
                         rep('Empeltre',5), rep('Ilo',6)),
                       levels=c('Sevillana','Ascolana','Empeltre','Ilo')),
  Rendimiento = c(4.9,8.5,9.4,9.8,7.4,10.5,
                  8.2,4.7,5.6,6.3,6.4,5.2,4.8,
                  5.6,4.9,5.0,4.7,4.3,
                  10.6,9.6,8.7,10.3,9.9,8.7)
)
knitr::kable(datos, col.names=c('Variedad','Rendimiento (t/ha)'),
             caption='Datos originales de rendimiento por unidad experimental.', digits=2)
Datos originales de rendimiento por unidad experimental.
Variedad Rendimiento (t/ha)
Sevillana 4.9
Sevillana 8.5
Sevillana 9.4
Sevillana 9.8
Sevillana 7.4
Sevillana 10.5
Ascolana 8.2
Ascolana 4.7
Ascolana 5.6
Ascolana 6.3
Ascolana 6.4
Ascolana 5.2
Ascolana 4.8
Empeltre 5.6
Empeltre 4.9
Empeltre 5.0
Empeltre 4.7
Empeltre 4.3
Ilo 10.6
Ilo 9.6
Ilo 8.7
Ilo 10.3
Ilo 9.9
Ilo 8.7

1.1 Resumen descriptivo

resumen <- datos %>% group_by(Tratamiento) %>%
  summarise(n=n(), media=mean(Rendimiento), mediana=median(Rendimiento),
            de=sd(Rendimiento), varianza=var(Rendimiento),
            minimo=min(Rendimiento), maximo=max(Rendimiento), .groups='drop')
knitr::kable(resumen, digits=3,
  col.names=c('Variedad','n','Media','Mediana','DE','Varianza','Mín.','Máx.'),
  caption='Resumen descriptivo por tratamiento.')
Resumen descriptivo por tratamiento.
Variedad n Media Mediana DE Varianza Mín. Máx.
Sevillana 6 8.417 8.95 2.031 4.126 4.9 10.5
Ascolana 7 5.886 5.60 1.220 1.488 4.7 8.2
Empeltre 5 4.900 4.90 0.474 0.225 4.3 5.6
Ilo 6 9.633 9.75 0.799 0.639 8.7 10.6

La asignación es desbalanceada: las variedades cuentan con 6, 7, 5 y 6 repeticiones, respectivamente. Las observaciones deben ser independientes por construcción del experimento; esto no puede verificarse solo mediante pruebas sobre los rendimientos.

2 Visualización exploratoria

2.1 Distribución del rendimiento por variedad

g_box <- ggplot(datos, aes(Tratamiento,Rendimiento,fill=Tratamiento)) +
  geom_boxplot(width=.57,alpha=.8,outlier.shape=NA,color='#344450') +
  geom_jitter(width=.09,height=0,size=2.6,alpha=.83,color='#273943') +
  stat_summary(fun=mean,geom='point',shape=23,size=3.7,
               fill='white',color='#253241',stroke=1) +
  scale_fill_manual(values=colores) +
  labs(title='Distribución del rendimiento',
       subtitle='Puntos: unidades experimentales | Rombos: media',
       x='Variedad',y='Rendimiento (t/ha)') + tema
g_box
Figura 1. Boxplots, observaciones individuales y medias (rombos blancos) por variedad.

Figura 1. Boxplots, observaciones individuales y medias (rombos blancos) por variedad.

2.2 Medias e intervalos de confianza descriptivos

medias <- resumen %>% mutate(
  ee=de/sqrt(n),
  li=media-qt(.975,df=n-1)*ee,
  ls=media+qt(.975,df=n-1)*ee)
g_medias <- ggplot(medias,aes(Tratamiento,media,color=Tratamiento)) +
  geom_errorbar(aes(ymin=li,ymax=ls),width=.14,linewidth=.8) +
  geom_point(size=3.8) +
  scale_color_manual(values=colores) +
  labs(title='Rendimiento medio e incertidumbre',
       subtitle='IC del 95 % calculados por separado en cada tratamiento',
       x='Variedad',y='Media del rendimiento (t/ha)') + tema
g_medias
Figura 2. Medias muestrales con intervalos t de confianza del 95 % por variedad (descriptivos, sin ajuste por comparaciones múltiples).

Figura 2. Medias muestrales con intervalos t de confianza del 95 % por variedad (descriptivos, sin ajuste por comparaciones múltiples).

3 ANOVA de una vía

El modelo clásico de efectos fijos es:

\[Y_{ij}=\mu+\tau_i+\varepsilon_{ij},\qquad \varepsilon_{ij}\overset{iid}{\sim}N(0,\sigma^2).\]

  • Hipótesis nula (\(H_0\)): las cuatro medias poblacionales son iguales.
  • Hipótesis alternativa (\(H_1\)): al menos una media es diferente.
modelo <- aov(Rendimiento ~ Tratamiento, data=datos)
tab_aov <- as.data.frame(summary(modelo)[[1]])
knitr::kable(tab_aov, digits=5,
  col.names=c('GL','Suma de cuadrados','Cuadrado medio','F','p'),
  caption='Tabla ANOVA de una vía.')
Tabla ANOVA de una vía.
GL Suma de cuadrados Cuadrado medio F p
Tratamiento 3 82.88976 27.62992 16.42183 1e-05
Residuals 20 33.65024 1.68251 NA NA
p_anova <- tab_aov[['Pr(>F)']][1]
eta2 <- tab_aov[['Sum Sq']][1]/sum(tab_aov[['Sum Sq']])

Resultado. \(F(3, 20)=16.422\), \(p\) < 0.001. El tamaño del efecto descriptivo \(\eta^2=0.711\) indica la proporción de variabilidad total explicada por el factor tratamiento en esta muestra.

4 Diagnóstico de los supuestos del ANOVA

4.1 Normalidad de residuos: Shapiro–Wilk

prueba_shapiro <- shapiro.test(residuals(modelo))
knitr::kable(data.frame(W=unname(prueba_shapiro$statistic),
                         p=prueba_shapiro$p.value),digits=5,
             caption='Shapiro–Wilk aplicado a residuos del ANOVA.')
Shapiro–Wilk aplicado a residuos del ANOVA.
W p
0.94672 0.22986

Interpretación: \(p\) = 0.2299. No se rechaza la hipótesis de normalidad residual. Una prueba no significativa no demuestra normalidad.

residuos_df <- data.frame(Ajustados=fitted(modelo),
                           Residuos=residuals(modelo),
                           Tratamiento=datos$Tratamiento)
g_qq <- ggplot(residuos_df,aes(sample=Residuos)) +
  stat_qq(size=2.5,color='#39796d',alpha=.8) +
  stat_qq_line(color='#be8251',linewidth=1) +
  labs(title='Normalidad: gráfico Q–Q',x='Cuantiles teóricos',
       y='Cuantiles observados de los residuos') + tema
g_qq
Figura 3. Gráfico Q–Q de residuos del ANOVA; desviaciones sistemáticas de la recta sugieren incumplimiento de normalidad.

Figura 3. Gráfico Q–Q de residuos del ANOVA; desviaciones sistemáticas de la recta sugieren incumplimiento de normalidad.

4.2 Homocedasticidad: Levene y Bartlett

prueba_levene <- car::leveneTest(Rendimiento ~ Tratamiento,
                                data=datos,center=median)
prueba_bartlett <- bartlett.test(Rendimiento ~ Tratamiento,data=datos)
comparacion_varianzas <- data.frame(
  Prueba=c('Levene (centrado en la mediana)','Bartlett'),
  Estadistico=c(prueba_levene[['F value']][1], unname(prueba_bartlett$statistic)),
  p=c(prueba_levene[['Pr(>F)']][1],prueba_bartlett$p.value))
knitr::kable(comparacion_varianzas,digits=5,
             caption='Contrastes de igualdad de varianzas.')
Contrastes de igualdad de varianzas.
Prueba Estadistico p
Levene (centrado en la mediana) 1.8990 0.16231
Bartlett 8.4254 0.03799
Precaución: Bartlett es especialmente sensible a apartamientos de la normalidad. Una discrepancia entre Levene y Bartlett debe motivar un análisis de sensibilidad, no una elección oportunista del resultado.
g_res <- ggplot(residuos_df,aes(Ajustados,Residuos,color=Tratamiento)) +
  geom_hline(yintercept=0,linetype='dashed',color='#768992') +
  geom_point(size=2.7,alpha=.85,
             position=position_jitter(width=.08,height=0)) +
  scale_color_manual(values=colores) +
  labs(title='Dispersión de residuos por valor ajustado',
       x='Rendimiento ajustado (t/ha)',y='Residuo') +
  tema + theme(legend.position='bottom')
g_res
Figura 4. Residuos frente a valores ajustados. Se inspeccionan dispersión, patrones y valores atípicos.

Figura 4. Residuos frente a valores ajustados. Se inspeccionan dispersión, patrones y valores atípicos.

4.3 Normalidad por tratamiento (complementaria)

sh_grupos <- do.call(rbind,lapply(split(datos$Rendimiento,datos$Tratamiento),
  function(x) data.frame(W=unname(shapiro.test(x)$statistic),
                         p=shapiro.test(x)$p.value)))
sh_grupos <- data.frame(Tratamiento=rownames(sh_grupos),sh_grupos,row.names=NULL)
knitr::kable(sh_grupos,digits=4,
             caption='Shapiro–Wilk por variedad; interpretarlo con cautela debido a n pequeño.')
Shapiro–Wilk por variedad; interpretarlo con cautela debido a n pequeño.
Tratamiento W p
Sevillana 0.9189 0.4975
Ascolana 0.8913 0.2813
Empeltre 0.9744 0.9024
Ilo 0.9021 0.3865

5 ANOVA de Welch: análisis de sensibilidad

Welch relaja la hipótesis de igualdad de varianzas y resulta especialmente pertinente cuando el diseño es desbalanceado.

prueba_welch <- oneway.test(Rendimiento ~ Tratamiento,data=datos,
                            var.equal=FALSE)
knitr::kable(data.frame(F=unname(prueba_welch$statistic),
                         gl_num=unname(prueba_welch$parameter[1]),
                         gl_den=unname(prueba_welch$parameter[2]),
                         p=prueba_welch$p.value),digits=5,
             caption='ANOVA de Welch (grados de libertad ajustados).')
ANOVA de Welch (grados de libertad ajustados).
F gl_num gl_den p
45.999 3 10.68583 0

6 Comparaciones múltiples: Tukey HSD

La prueba de Tukey se presenta como seguimiento del ANOVA clásico. Bajo heterocedasticidad relevante, considerar Games–Howell como alternativa.

tukey <- TukeyHSD(modelo)
tukey_tab <- data.frame(Comparacion=rownames(tukey$Tratamiento),
                         as.data.frame(tukey$Tratamiento),row.names=NULL,
                         check.names=FALSE)
knitr::kable(tukey_tab,digits=4,
  col.names=c('Comparación','Diferencia','Límite inferior','Límite superior','p ajustado'),
  caption='Comparaciones por pares de Tukey, con IC simultáneos al 95 %.')
Comparaciones por pares de Tukey, con IC simultáneos al 95 %.
Comparación Diferencia Límite inferior Límite superior p ajustado
Ascolana-Sevillana -2.5310 -4.5508 -0.5111 0.0110
Empeltre-Sevillana -3.5167 -5.7151 -1.3183 0.0012
Ilo-Sevillana 1.2167 -0.8794 3.3128 0.3880
Empeltre-Ascolana -0.9857 -3.1115 1.1401 0.5748
Ilo-Ascolana 3.7476 1.7278 5.7675 0.0002
Ilo-Empeltre 4.7333 2.5349 6.9317 0.0000
tukey_plot <- data.frame(
  comparacion=rownames(tukey$Tratamiento),
  diferencia=tukey$Tratamiento[,'diff'],
  li=tukey$Tratamiento[,'lwr'],
  ls=tukey$Tratamiento[,'upr'],
  significativo=tukey$Tratamiento[,'p adj']<.05)
g_tukey <- ggplot(tukey_plot,aes(x=reorder(comparacion,diferencia),y=diferencia,
                               color=significativo)) +
  geom_hline(yintercept=0,linetype='dashed',color='#768992') +
  geom_errorbar(aes(ymin=li,ymax=ls),width=.15,linewidth=.8) +
  geom_point(size=3) + coord_flip() +
  scale_color_manual(values=c('TRUE'='#39796d','FALSE'='#a6aeb3')) +
  labs(title='Comparaciones múltiples de Tukey',
       subtitle='Intervalos simultáneos de confianza del 95 %',
       x='Contraste (primera variedad − segunda variedad)',
       y='Diferencia de medias (t/ha)') + tema
g_tukey
Figura 5. Diferencias de medias e intervalos simultáneos de Tukey (95 %). Los intervalos que cruzan cero no indican diferencia estadísticamente significativa.

Figura 5. Diferencias de medias e intervalos simultáneos de Tukey (95 %). Los intervalos que cruzan cero no indican diferencia estadísticamente significativa.

7 Kruskal–Wallis

Kruskal–Wallis utiliza rangos. No exige normalidad ni homocedasticidad para contrastar igualdad de distribuciones, pero sí requiere independencia. Su interpretación específica como comparación de medianas exige distribuciones de forma y dispersión comparables.

  • \(H_0\): las distribuciones de rendimiento son iguales entre los cuatro tratamientos.
  • \(H_1\): al menos una distribución difiere.
prueba_kw <- kruskal.test(Rendimiento ~ Tratamiento,data=datos)
knitr::kable(data.frame(H=unname(prueba_kw$statistic),
                        gl=unname(prueba_kw$parameter),
                        p=prueba_kw$p.value),digits=5,
             caption='Prueba de Kruskal–Wallis con corrección por empates.')
Prueba de Kruskal–Wallis con corrección por empates.
H gl p
15.22975 3 0.00163

Resultado: \(H(3)=15.23\), \(p\) = 0.0016.

7.1 Comparaciones múltiples: Dunn (Holm)

resultado_dunn <- FSA::dunnTest(Rendimiento ~ Tratamiento,
                              data=datos,method='holm')$res
knitr::kable(resultado_dunn,digits=5,
  col.names=c('Comparación','Z','p sin ajustar','p ajustado (Holm)'),
  caption='Pruebas de Dunn por pares, con control de multiplicidad de Holm.')
Pruebas de Dunn por pares, con control de multiplicidad de Holm.
Comparación Z p sin ajustar p ajustado (Holm)
Sevillana - Ascolana 1.79000 0.07345 0.22036
Sevillana - Empeltre 2.48947 0.01279 0.05117
Ascolana - Empeltre 0.87369 0.38229 0.38229
Sevillana - Ilo -1.00108 0.31679 0.63358
Ascolana - Ilo -2.82887 0.00467 0.02336
Empeltre - Ilo -3.44396 0.00057 0.00344

8 Síntesis e interpretación

Resumen de los contrastes estadísticos realizados.
Procedimiento p Decision
ANOVA clásico 0.00001 p < 0.05
Shapiro–Wilk (residuos) 0.22986 p ≥ 0.05
Levene (mediana) 0.16231 p ≥ 0.05
Bartlett 0.03799 p < 0.05
ANOVA de Welch 0.00000 p < 0.05
Kruskal–Wallis 0.00163 p < 0.05

El ANOVA detecta diferencias estadísticamente significativas entre las medias. Kruskal–Wallis también detecta diferencias globales entre las distribuciones. El rendimiento más alto observado corresponde a Ilo (9.63 t/ha) y el menor a Empeltre (4.90 t/ha).

Conclusión metodológica. Las pruebas de supuestos deben interpretarse conjuntamente con los gráficos. El resultado global informa si hay evidencia de diferencias; las comparaciones múltiples permiten identificar qué pares difieren. El diseño aleatorizado y la independencia de las unidades experimentales son condiciones del estudio, no resultados de Shapiro–Wilk, Levene o Kruskal–Wallis.

9 Exportación opcional de figuras y datos

El siguiente bloque se mantiene oculto por defecto. Cambie eval=FALSE a eval=TRUE para exportar los archivos a su directorio de trabajo.

ggsave('Figura_1_Boxplot.png',g_box,width=9,height=5.5,dpi=300)
ggsave('Figura_2_Medias_IC.png',g_medias,width=9,height=5.5,dpi=300)
ggsave('Figura_3_QQplot.png',g_qq,width=9,height=5.5,dpi=300)
ggsave('Figura_4_Residuos.png',g_res,width=9,height=5.5,dpi=300)
ggsave('Figura_5_Tukey.png',g_tukey,width=9,height=5.5,dpi=300)
write.csv(datos,'Datos_Aceitunas.csv',row.names=FALSE)

Reproducibilidad: para generar este informe en RStudio, abra el archivo .Rmd, instale los paquetes requeridos y pulse Knit. También puede ejecutar rmarkdown::render('Informe_DCA_Aceitunas.Rmd') (requiere el paquete rmarkdown).