datos <- dat
datos$Env <- factor(datos$Env)
datos$RepEnv <- factor(paste(datos$Env, datos$Rep)) # replication within environment
datos$G <- factor(paste(datos$Line, datos$Tester)) # genotype (all entries)
cr <- droplevels(subset(datos, Line != "" & Tester != "")) # crosses
par <- droplevels(subset(datos, Line == "" | Tester == "")) # parents (line- or tester-only)
cr$Line <- factor(cr$Line); cr$Tester <- factor(cr$Tester)
par$Par <- factor(paste(par$Line, par$Tester))
# 1. Top-level combined model: Env, Rep(Env), Treatments (G) and Treatments x Env
A <- as.matrix(anova(aov(Yield ~ Env + RepEnv + G + Env:G, data = datos)))
ss_env <- A["Env", 2]; df_env <- A["Env", 1]
ss_rep <- A["RepEnv", 2]; df_rep <- A["RepEnv", 1]
ss_G <- A["G", 2]; df_G <- A["G", 1] # Treatments
ss_eG <- A["Env:G", 2]; df_eG <- A["Env:G", 1] # E x Treatments
ss_err <- A["Residuals", 2]; df_err <- A["Residuals", 1] # Error
# 2. Treatments partition -> Parents / Parents-vs-Crosses / Crosses (Lines, Testers, L x T)
mp <- as.matrix(anova(aov(Yield ~ Par, data = par)))
ss_par <- mp["Par", 2]; df_par <- mp["Par", 1]
mc <- as.matrix(anova(aov(Yield ~ Line * Tester, data = cr)))
ss_line <- mc["Line", 2]; ss_test <- mc["Tester", 2]; ss_lt <- mc["Line:Tester", 2]
df_line <- mc["Line", 1]; df_test <- mc["Tester", 1]; df_lt <- mc["Line:Tester", 1]
ss_cross <- ss_line + ss_test + ss_lt; df_cross <- df_line + df_test + df_lt
ss_pvc <- ss_G - ss_par - ss_cross; df_pvc <- df_G - df_par - df_cross
# 3. Treatments x Environment partition
mcE <- as.matrix(anova(aov(Yield ~ Env * Line * Tester, data = cr)))
ss_eline <- mcE["Env:Line", 2]; ss_etest <- mcE["Env:Tester", 2]; ss_elt <- mcE["Env:Line:Tester", 2]
df_eline <- mcE["Env:Line", 1]; df_etest <- mcE["Env:Tester", 1]; df_elt <- mcE["Env:Line:Tester", 1]
ss_ecross <- ss_eline + ss_etest + ss_elt; df_ecross <- df_eline + df_etest + df_elt
mpE <- as.matrix(anova(aov(Yield ~ Env * Par, data = par)))
ss_epar <- mpE["Env:Par", 2]; df_epar <- mpE["Env:Par", 1]
ss_epvc <- ss_eG - ss_epar - ss_ecross; df_epvc <- df_eG - df_epar - df_ecross
# 4.parents-included pooled ANOVA (published row order)
mk <- function(df, ss) c(df, ss, ss / df, NA, NA)
tab <- rbind(
`Environment (E)` = mk(df_env, ss_env),
`Rep / Env` = mk(df_rep, ss_rep),
Treatments = mk(df_G, ss_G),
Parents = mk(df_par, ss_par),
`Parents vs Crosses` = mk(df_pvc, ss_pvc),
Crosses = mk(df_cross, ss_cross),
Lines = mk(df_line, ss_line),
Testers = mk(df_test, ss_test),
`Line x Tester` = mk(df_lt, ss_lt),
`E x Treatments` = mk(df_eG, ss_eG),
`E x Parents` = mk(df_epar, ss_epar),
`E x Parents vs Crosses` = mk(df_epvc, ss_epvc),
`E x Crosses` = mk(df_ecross, ss_ecross),
`E x Lines` = mk(df_eline, ss_eline),
`E x Testers` = mk(df_etest, ss_etest),
`E x Line x Tester` = mk(df_elt, ss_elt),
Error = mk(df_err, ss_err))
colnames(tab) <- c("Df", "Sum Sq", "Mean Sq", "F value", "Pr(>F)")
# 5. F-tests -- environments RANDOM (f_test = "interaction"): each combining-ability
denom <- c(
"Environment (E)" = "Error", "Rep / Env" = "Error",
"Treatments" = "E x Treatments", "Parents" = "E x Parents",
"Parents vs Crosses" = "E x Parents vs Crosses", "Crosses" = "E x Crosses",
"Lines" = "E x Lines", "Testers" = "E x Testers", "Line x Tester" = "E x Line x Tester",
"E x Treatments" = "Error", "E x Parents" = "Error",
"E x Parents vs Crosses" = "Error", "E x Crosses" = "Error",
"E x Lines" = "Error", "E x Testers" = "Error", "E x Line x Tester" = "Error")
for (rn in names(denom)) {
d <- denom[[rn]]; ms <- tab[d, "Mean Sq"]; dd <- tab[d, "Df"]
if (is.na(ms) || ms <= 0) next
tab[rn, "F value"] <- tab[rn, "Mean Sq"] / ms
tab[rn, "Pr(>F)"] <- pf(tab[rn, "F value"], tab[rn, "Df"], dd, lower.tail = FALSE)
}
ANOVA_full <- as.data.frame(tab) # full parents-included pooled combined ANOVA
ANOVA_full