Validation and the corrections of the earlier version

Muhammad Yaseen

2026-11-05

1 Abstract

Every result is checked against an independent computation. This vignette shows the main checks and lists the corrections of the earlier version, each with its effect on ge_data.

2 Analyses of variance against lm()

aa <-
  add_anova(
      .data = ge_data
    , .y    = Yield
    , .rep  = Rep
    , .gen  = Gen
    , .env  = Env
    )
a2 <- anova(lm(formula = terms(Yield ~ Env + Env:Rep + Gen + Gen:Env, keep.order = TRUE), data = ge_data))
all.equal(target = aa$anova[["Sum Sq"]], current = a2[["Sum Sq"]])
[1] TRUE

3 Regression against lm()

reg <-
  stab_reg(
      .data = ge_data
    , .y    = Yield
    , .rep  = Rep
    , .gen  = Gen
    , .env  = Env
    )
M <- with(data = ge_data, expr = tapply(X = Yield, INDEX = list(Gen, Env), FUN = mean))
b <-
  vapply(
      X         = reg$StabIndvReg$Gen
    , FUN       = function(g) coef(lm(M[g, ] ~ colMeans(M)))[[2]]
    , FUN.VALUE = 0
    )
all.equal(target = reg$StabIndvReg$Slope, current = unname(b))
[1] TRUE

4 Eskridge (1990), Table 4

Eskridge’s Table 4 gives the four safety-first indices of 12 CIMMYT entries at \(\alpha = 0.05\), computed from the summaries of his Table 3 (means, variances, slopes, Shukla’s variances, deviation mean squares, with \(S^2_y = 1.87\), \(\hat{\sigma}^2_E = 1.80\) and \(E = 15\)). The package’s core recomputes all 48 values from the same summaries:

ref <-
  stab_reference(
      source   = "Eskridge"
    , evaluate = TRUE
    , level    = 1
    )
tab <- ref[, list(
    quantity  = sub(pattern = " \\(alpha.*", replacement = "", x = quantity)
  , published = value
  , computed  = round(x = computed, digits = 3)
  , agrees
  )]
tab
          quantity published computed agrees
            <char>     <num>    <num> <lgcl>
 1:  EV of entry 1      2.24    2.239   TRUE
 2:  EV of entry 2      2.04    2.045   TRUE
 3:  EV of entry 3      1.72    1.717   TRUE
 4:  EV of entry 4      2.14    2.139   TRUE
 5:  EV of entry 5      1.46    1.462   TRUE
 6:  EV of entry 6      1.90    1.903   TRUE
 7:  EV of entry 7      1.67    1.668   TRUE
 8:  EV of entry 8      1.74    1.740   TRUE
 9:  EV of entry 9      2.83    2.826   TRUE
10: EV of entry 10      2.36    2.360   TRUE
11: EV of entry 11      2.26    2.265  FALSE
12: EV of entry 12      2.49    2.487   TRUE
13:  FW of entry 1      4.52    4.516   TRUE
14:  FW of entry 2      4.38    4.381   TRUE
15:  FW of entry 3      3.76    3.756   TRUE
16:  FW of entry 4      3.81    3.812   TRUE
17:  FW of entry 5      3.87    3.874   TRUE
18:  FW of entry 6      4.28    4.279   TRUE
19:  FW of entry 7      4.03    4.033   TRUE
20:  FW of entry 8      4.17    4.063  FALSE
21:  FW of entry 9      4.16    4.158   TRUE
22: FW of entry 10      4.33    4.334   TRUE
23: FW of entry 11      3.10    3.099   TRUE
24: FW of entry 12      4.60    4.600   TRUE
25:  SH of entry 1      2.47    2.471   TRUE
26:  SH of entry 2      2.20    2.199   TRUE
27:  SH of entry 3      1.58    1.581   TRUE
28:  SH of entry 4      1.81    1.811   TRUE
29:  SH of entry 5      1.75    1.755   TRUE
30:  SH of entry 6      2.18    2.179   TRUE
31:  SH of entry 7      2.20    2.197   TRUE
32:  SH of entry 8      2.17    2.166   TRUE
33:  SH of entry 9      2.28    2.279   TRUE
34: SH of entry 10      2.19    2.192   TRUE
35: SH of entry 11      1.41    1.409   TRUE
36: SH of entry 12      2.24    2.239   TRUE
37:  ER of entry 1      4.34    4.356  FALSE
38:  ER of entry 2      3.85    3.844  FALSE
39:  ER of entry 3      3.12    3.122   TRUE
40:  ER of entry 4      3.35    3.363  FALSE
41:  ER of entry 5      3.18    3.174  FALSE
42:  ER of entry 6      3.70    3.709  FALSE
43:  ER of entry 7      3.67    3.679  FALSE
44:  ER of entry 8      3.55    3.502  FALSE
45:  ER of entry 9      3.78    3.763  FALSE
46: ER of entry 10      3.76    3.751  FALSE
47: ER of entry 11      2.86    2.854  FALSE
48: ER of entry 12      3.73    3.730   TRUE
          quantity published computed agrees
            <char>     <num>    <num> <lgcl>
sum(ref$agrees)
[1] 36
max(abs(ref$computed - ref$value)[!grepl(pattern = "entry 8", x = ref$quantity)])
[1] 0.01660005

Of the 48 values, 36 agree to the two printed decimals. The remaining ones differ by at most 0.02, because the summaries of Table 3 are printed to two decimals, with one exception. For entry 8, Table 3 prints the slope \(b = 1.27\), the same as for entry 7; the published FW (4.17) and ER (3.55) of entry 8 both fit \(b = 1.22\), so the printed slope appears to be a misprint. stab_reference() gives the reason for every difference in the column note.

5 Order of the rows

The earlier version attached stability statistics to the wrong genotypes when the data were not sorted by genotype. The results no longer depend on the order of the rows:

set.seed(seed = 1)
shuffled <- ge_data[sample(x = nrow(ge_data)), ]
k1 <-
  stab_kang(
      .data = ge_data
    , .y    = Yield
    , .rep  = Rep
    , .gen  = Gen
    , .env  = Env
    )$Kang
k2 <-
  stab_kang(
      .data = shuffled
    , .y    = Yield
    , .rep  = Rep
    , .gen  = Gen
    , .env  = Env
    )$Kang
all.equal(target = k1, current = k2)
[1] TRUE

6 Corrections

Function Earlier version Now
stab_kang, stab_asv, stab_masv, stab_dist, stab_reg, AMMI1 plot statistics attached to other genotypes unless the data were sorted by genotype each statistic on its genotype
indiv_anova genotypes only in each environment randomized complete blocks (replicates in the model)
er_anova Total and Gen from the replicate line; deviations divided by \(B\); error df \(EG(B-1)\) Eberhart and Russell’s lines; error df \(E(G-1)(B-1)\)
stab_reg Delta = deviation SS divided by \(B\) Delta = \(S^2_{d_i}\) with its test
stab_par parameters divided by \(B\); error df \((G-1)^2E\); rating +2 at alpha; one-sided LSD; covariate per plot scale of the means; error df \(E(G-1)(B-1)\); rating \(-2\); two-sided LSD; covariate per environment
stab_fox plots ranked and counted (up to 12 of 11 environments) genotype means ranked in each environment
stab_asv \(\lambda_1/\lambda_2\) on the squared score \(SS_1/SS_2\) on the score
stab_masv ratios of singular values ratios of sums of squares
ammi an axis with a zero singular value the axes that exist

7 Summary

The analyses of variance and the regressions agree with lm(); the stability statistics follow their published formulas and no longer depend on the order of the data.

8 References

Eskridge, K. M. (1990). Selection of stable cultivars using a safety-first rule. Crop Science, 30(2), 369–374.

Eberhart, S. A. and Russell, W. A. (1966). Stability parameters for comparing varieties. Crop Science, 6(1), 36–40.

Purchase, J. L., Hatting, H. and van Deventer, C. S. (2000). Genotype x environment interaction of winter wheat in South Africa: II. Stability analysis of yield performance. South African Journal of Plant and Soil, 17(3), 101–107.

Zali, H., Farshadfar, E., Sabaghpour, S. H. and Karimizadeh, R. (2012). Evaluation of genotype x environment interaction in chickpea using measures of stability from AMMI model. Annals of Biological Research, 3(7), 3126–3136.

Fox, P. N., Skovmand, B., Thompson, B. K., Braun, H. J. and Cormier, R. (1990). Yield and adaptation of hexaploid spring triticale. Euphytica, 47(1), 57–64.