Llegamos a un diseño sumamente especializado y de altísimo valor para el programa de Ingeniería Agrícola: el Diseño de Bloques Aumentados (también conocido como diseño de Federer).
En los programas de mejoramiento genético vegetal (por ejemplo, desarrollando nuevas variedades de arroz o yuca), los ingenieros suelen tener cientos de genotipos nuevos, pero muy poca semilla de cada uno, por lo que no pueden hacer repeticiones. La genialidad de este diseño radica en colocar unos pocos tratamientos “testigos” (variedades comerciales) repetidos en todos los bloques para estimar el error y el efecto del bloque, y luego “aumentar” esos bloques con los tratamientos nuevos sin repetición.
Aquí tienes la estructura pedagógica para tu octavo cuaderno.
El Diseño de Bloques Aumentados resuelve el problema de evaluar un gran número de tratamientos nuevos (\(n\)) cuando el material experimental es tan escaso que no permite repeticiones.
Para lograrlo, el experimento se divide en \(b\) bloques. En cada bloque se asignan aleatoriamente \(c\) tratamientos testigos (que sí se repiten en todos los bloques) y una fracción de los tratamientos nuevos (que aparecen una sola vez en todo el experimento). El error experimental y los efectos espaciales de los bloques se calculan exclusivamente a partir del comportamiento de los testigos.
El Modelo Estadístico Lineal: \[y_{ij} = \mu + \tau_i + \beta_j + \epsilon_{ij}\]
Donde: * \(y_{ij}\): Respuesta del \(i\)-ésimo tratamiento en el \(j\)-ésimo bloque. * \(\mu\): Media general. * \(\tau_i\): Efecto del \(i\)-ésimo tratamiento (puede ser un testigo o uno nuevo). * \(\beta_j\): Efecto del \(j\)-ésimo bloque. * \(\epsilon_{ij}\): Error experimental (estimado solo con los testigos).
Tabla ANOVA Generalizada: La suma de cuadrados de los tratamientos se desglosa para evaluar comparaciones específicas de alto interés agronómico.
| Fuente de Variación | Grados de Libertad (GL) | Suma de Cuadrados (SC) | Cuadrado Medio (CM) |
|---|---|---|---|
| Bloques (Ajustados) | \(b - 1\) | \(SCB_{adj}\) | \(\frac{SCB_{adj}}{b-1}\) |
| Tratamientos (No Ajustados) | \(t - 1\) | \(SCTr\) | \(\frac{SCTr}{t-1}\) |
| \(\rightarrow\) Testigos | \(c - 1\) | \(SCTestigos\) | \(\frac{SCTestigos}{c-1}\) |
| \(\rightarrow\) Nuevos | \(n - 1\) | \(SCNuevos\) | \(\frac{SCNuevos}{n-1}\) |
| \(\rightarrow\) Testigos vs Nuevos | \(1\) | \(SCTvsN\) | \(\frac{SCTvsN}{1}\) |
| Error | \((c - 1)(b - 1)\) | \(SCE\) | \(\frac{SCE}{GL_E}\) |
| Total | \(N - 1\) | \(SCT\) |
(Nota: \(c\) = número de testigos, \(n\) = número de tratamientos nuevos, \(b\) = bloques, \(t = c + n\)).
El método original de Federer para calcular a mano este diseño es muy intuitivo y perfecto para que tus alumnos lo practiquen:
Para easyanova, usaremos el data8. La clave
del EDA aquí es que los alumnos visualicen visualmente quiénes son los
“testigos” (tienen datos en todos los bloques) y quiénes son los
“nuevos” (tienen un solo dato).
library(easyanova)
# Cargar el dataset de ejemplo para Bloques Aumentados
data(data8)
# Col 1 = Tratamiento, Col 2 = Bloque, Col 3 = Respuesta
head(data8)
# EDA: Identificar la estructura de Testigos vs Nuevos
# Calculamos la frecuencia de cada tratamiento
frecuencias <- table(data8[,1])
testigos <- names(frecuencias[frecuencias > 1])
nuevos <- names(frecuencias[frecuencias == 1])
cat("Tratamientos Testigos (Repetidos):", testigos, "\n")
cat("Cantidad de Tratamientos Nuevos (Sin repetición):", length(nuevos), "\n")
# Gráfico para comparar la dispersión de los testigos vs los valores únicos de los nuevos
library(ggplot2)
# Crear una columna temporal para clasificar si es testigo o nuevo
data8$Tipo <- ifelse(data8[,1] %in% testigos, "Testigo (Control)", "Nuevo (Material Genético)")
ggplot(data8, aes(x = Tipo, y = data8[,3], color = Tipo)) +
geom_jitter(width = 0.2, size = 3, alpha = 0.7) +
labs(title = "Dispersión: Testigos Comerciales vs Nuevos Genotipos",
subtitle = "Los testigos permiten medir el error; los nuevos buscan superar a los testigos",
x = "Clasificación del Genotipo",
y = "Rendimiento Observado") +
theme_minimal() +
theme(legend.position = "none")
Propósito pedagógico: Este gráfico de “jitter” (puntos dispersos) mostrará una nube densa para los testigos y puntos individuales esparcidos para los nuevos genotipos. La pregunta para el estudiante es: “A simple vista, ¿hay algún punto de los ‘Nuevos’ que esté claramente por encima de la nube de los ‘Testigos’?”
easyanovaLa ejecución requiere especificar design = 8. El paquete
identifica automáticamente cuáles son los testigos analizando las
repeticiones en la columna de tratamientos.
# Ejecutar Diseño de Bloques Aumentados (design = 8)
# Orden requerido: Col 1 = Tratamiento, Col 2 = Bloque, Col 3 = Respuesta
resultado_aumentado <- ea1(data8, design = 8)
# Imprimir los resultados
# Prestar especial atención a los contrastes (Testigos vs Nuevos) y a las Medias Ajustadas
print(resultado_aumentado)
Pide a tus alumnos que copien la salida de easyanova y
te consulten (a mí) con estos prompts:
En Python (Usando statsmodels y manipulación con
pandas): En Python, el modelo lineal general
maneja los diseños desbalanceados inherentemente, pero la lógica de los
bloques aumentados requiere tratar los datos como un gran modelo de
efectos fijos.
import pandas as pd
import statsmodels.api as sm
from statsmodels.formula.api import ols
# Dataset simulado (Testigos: C1, C2. Nuevos: N1 a N4 distribuidos en 2 bloques)
data = {
'Tratamiento': ['C1','C2', 'N1','N2', 'C1','C2', 'N3','N4'],
'Bloque': ['B1','B1', 'B1','B1', 'B2','B2', 'B2','B2'],
'Respuesta': [20, 22, 25, 18, 21, 24, 19, 28]
}
df = pd.DataFrame(data)
# Ajuste del modelo lineal
modelo_aumentado = ols('Respuesta ~ C(Bloque) + C(Tratamiento)', data=df).fit()
# Usamos ANOVA Tipo II o III debido al fuerte desbalance (los nuevos tienen N=1)
tabla_anova = sm.stats.anova_lm(modelo_aumentado, typ=2)
print("\n--- Tabla ANOVA (Bloques Aumentados) ---")
print(tabla_anova)
# Nota: Para el cálculo exacto de contrastes de Federer en Python se suelen requerir rutinas manuales.
En Julia (Usando DataFrames y
GLM):
using DataFrames, GLM
# DataFrame simulado
df = DataFrame(
Tratamiento = ["C1","C2", "N1","N2", "C1","C2", "N3","N4"],
Bloque = ["B1","B1", "B1","B1", "B2","B2", "B2","B2"],
Respuesta = [20.0, 22.0, 25.0, 18.0, 21.0, 24.0, 19.0, 28.0]
)
df.Tratamiento = categorical(df.Tratamiento)
df.Bloque = categorical(df.Bloque)
# Ajuste del modelo general
modelo_aumentado = lm(@formula(Respuesta ~ Bloque + Tratamiento), df)
println("--- Resumen del Modelo (Bloques Aumentados) ---")
println(modelo_aumentado)