Reproducing Perez-Elizalde et al. (2012)

Muhammad Yaseen

2026-11-09

1 Abstract

Perez-Elizalde et al. (2012, Section 3.2) analysed the second year of the maize trial with the first year as prior and all 11 bilinear terms. This vignette repeats their analysis and compares it with Table B.1 (the 38 linear effects), Table 2 (\(\sigma\), the singular values and the significant scores) and Figure 4 (the biplot).

2 The fit

The paper used two chains of 20,000 iterations. Here two chains of 5000 after a burn-in of 1000 suffice for the comparison.

fm <-
  bayes_ammi(
      .data       = cultivo2009
    , .y          = y
    , .gen        = entry
    , .env        = site
    , .rep        = rep
    , .nIter      = 5000
    , .prior_data = cultivo2008
    , .n0         = NULL
    , .model      = "AMMI"
    , .k          = NULL
    , .burnin     = 1000
    , .thin       = 1
    , .chains     = 2
    , .priors     = bys_priors(
          mu_mean     = 0
        , mu_var      = 1e+8
        , tau_mean    = 0
        , tau_var     = 1e+8
        , delta_mean  = 0
        , delta_var   = 1e+8
        , lambda_mean = 0
        , lambda_var  = 1e+8
        , nu          = 1
        , s2          = NULL
        )
    , .level      = 0.95
    , .seed       = 2012
    , .align      = TRUE
    , .waic       = TRUE
    )
s <- fm$summary
c(max_rhat = max(s$rhat), min_ess_linear = min(s[block %in% c("mu", "tau", "delta"), ess]))
      max_rhat min_ess_linear 
      1.004002    9162.831481 

3 Table B.1: the linear effects

pub <- utils::read.csv(file = system.file("extdata", "perez2012.csv", package = "baystability"))
pos <- c("mu", sprintf("tau[%d]", 1:12), sprintf("delta[%d]", 1:25))
lin <- s[block %in% c("mu", "tau", "delta")]
b1 <- data.table::data.table(
    parameter = c("mu", sprintf("alpha%d", 1:12), sprintf("beta%d", 1:25))
  , published = pub$mean[match(x = pos, table = pub$parameter)]
  , here      = round(x = lin$mean, digits = 1)
  , sd_pub    = pub$sd[match(x = pos, table = pub$parameter)]
  , sd_here   = round(x = lin$sd, digits = 2)
  )
b1[, diff_in_sd := round(x = (here - published) / sd_pub, digits = 3)]
b1
    parameter published    here sd_pub sd_here diff_in_sd
       <char>     <num>   <num>  <num>   <num>      <num>
 1:        mu   3848.00  3848.2  30.68   30.65      0.007
 2:    alpha1    135.90   137.3 102.92  102.51      0.014
 3:    alpha2    317.50   316.6 102.29  102.68     -0.009
 4:    alpha3    -64.68   -62.8 103.26  102.65      0.018
 5:    alpha4      2.75     3.6 102.62  101.72      0.008
 6:    alpha5     93.39    93.0 101.90  101.66     -0.004
 7:    alpha6    181.00   183.7 101.81  102.67      0.027
 8:    alpha7    499.30   499.3 103.21  101.78      0.000
 9:    alpha8     64.30    62.9 102.72  100.77     -0.014
10:    alpha9    129.30   127.0 102.34  102.77     -0.022
11:   alpha10   -479.00  -480.5 103.10  102.47     -0.015
12:   alpha11   -270.10  -271.0 103.02  101.72     -0.009
13:   alpha12   -609.70  -609.2 102.61  101.09      0.005
14:     beta1    134.50   133.7 151.21  151.32     -0.005
15:     beta2   -533.60  -533.8 151.39  149.93     -0.001
16:     beta3    864.20   866.0 151.39  151.13      0.012
17:     beta4   -377.40  -379.7 151.37  149.94     -0.015
18:     beta5   1537.00  1533.9 150.94  150.48     -0.021
19:     beta6    -96.78   -95.2 150.28  150.16      0.011
20:     beta7  -1761.00 -1758.0 151.22  151.11      0.020
21:     beta8    348.20   347.8 151.61  150.13     -0.003
22:     beta9  -1468.00 -1468.1 150.96  151.87     -0.001
23:    beta10   -745.10  -745.4 150.44  152.31     -0.002
24:    beta11  -1202.00 -1201.6 151.64  152.25      0.003
25:    beta12  -1900.00 -1901.0 152.11  150.13     -0.007
26:    beta13   -971.60  -971.6 150.75  151.05      0.000
27:    beta14   -548.60  -546.1 151.84  150.85      0.016
28:    beta15  -2215.00 -2214.6 151.62  151.90      0.003
29:    beta16     87.58    84.4 150.95  150.70     -0.021
30:    beta17    160.40   160.4 152.11  149.99      0.000
31:    beta18   1848.00  1842.7 152.18  150.60     -0.035
32:    beta19   -865.20  -866.8 150.62  153.13     -0.011
33:    beta20  -1112.00 -1110.6 151.82  150.01      0.009
34:    beta21  -1627.00 -1623.9 151.76  150.46      0.020
35:    beta22   4917.00  4918.5 151.56  152.80      0.010
36:    beta23   2865.00  2864.4 151.21  150.72     -0.004
37:    beta24    911.80   913.6 149.76  150.20      0.012
38:    beta25   1749.00  1751.0 150.27  149.69      0.013
    parameter published    here sd_pub sd_here diff_in_sd
       <char>     <num>   <num>  <num>   <num>      <num>

All 38 posterior means agree with the published ones to within 0.035 posterior standard deviations, and the standard deviations agree too.

3.1 Why the posterior means are averages of the two years

With \(n_0 = B = 3\) the earlier trial weighs as much as the new one, so the posterior mean of every linear effect is the average of its two least-squares estimates:

both <-
  bys_ls_means(
      .data = rbind(
          cultivo2008[c("site", "rep", "entry", "y")]
        , cultivo2009[c("site", "rep", "entry", "y")]
        )
    , .y    = y
    , .gen  = entry
    , .env  = site
    )
c(average_mu = both$grand_mean, published = 3848)
average_mu  published 
  3848.275   3848.000 

4 Table 2: the residual standard deviation and the singular values

sig <- sqrt(unlist(fm$tau1))
lam <- s[block == "lambda"]
t2 <- data.table::data.table(
    parameter = c("sigma", sprintf("lambda%d", 1:11))
  , published = pub$mean[match(x = c("sigma", sprintf("lambda[%d]", 1:11)), table = pub$parameter)]
  , here      = round(c(mean(sig), lam$mean))
  , sd_pub    = pub$sd[match(x = c("sigma", sprintf("lambda[%d]", 1:11)), table = pub$parameter)]
  , sd_here   = round(c(sd(sig), lam$sd))
  )
t2[, ratio := round(x = here / published, digits = 2)]
t2
    parameter published  here sd_pub sd_here ratio
       <char>     <num> <num>  <num>   <num> <num>
 1:     sigma    1311.0  1305  39.13      39  1.00
 2:   lambda1    2572.0  3667 451.76     393  1.43
 3:   lambda2    2354.0  3286 388.40     349  1.40
 4:   lambda3    2123.0  2824 340.34     317  1.33
 5:   lambda4    1815.0  2496 328.85     301  1.38
 6:   lambda5    1576.0  2217 317.49     302  1.41
 7:   lambda6    1262.0  1852 311.66     301  1.47
 8:   lambda7     992.0  1535 297.34     292  1.55
 9:   lambda8     762.6  1247 283.71     289  1.64
10:   lambda9     506.1   945 260.09     286  1.87
11:  lambda10     315.4   652 217.51     277  2.07
12:  lambda11     167.4   335 153.72     241  2.00

The residual standard deviation agrees: 1305.2 against 1311.00, 0.15 posterior standard deviations apart.

The singular values do not agree: here they are 1.33 to 2.07 times the published ones. By eq. 2.15 the posterior mean of \(\lambda_k\) is close to \((n_0\lambda_{0k} + B\,\va_k^\top\mY\vg_k)/(n_0 + B)\). Here \(\lambda_{01} =\) 5306 is the first singular value of the first year. With equal weights, a published \(\lambda_1 = 2572\) below \(\lambda_{01}/2 =\) 2653 would need \(\va_1^\top\mY\vg_1\) to be negative on average, that is, the second-year data pulling the first term against itself. The leading published values are close to \(\lambda_{0k}/2\), as if the second year added nothing to them.

Two explanations were checked with the sampler of this package (dev/lambda-checks.R in the source) and neither gives the published values:

The linear effects and \(\sigma\), which come from the same draws, are reproduced; the sampler gives the same draws as an independent R version of eq. 2.15 and recovers the true values of simulated trials (validation vignette). The published singular values therefore disagree with the method as the paper states it, and the difference lies in the article, through a step it does not report or an error in its Table 2, rather than in the package.

5 Table 2: the significant scores

The paper lists the scores whose bivariate 0.95 HPD region excludes the origin: genotype 12 on the second term and environments 5, 9, 23 and 25 on the first.

sc <- s[block %in% c("alpha", "gamma") & axis %in% 1:2]
sc[(block == "alpha" & label == levels(factor(cultivo2009$entry))[12]) |
     (block == "gamma" & label %in% c("5", "9", "23", "25")), list(
         parameter
       , axis
       , mean
       , sd
       , lower
       , upper
       )]
      parameter  axis       mean         sd       lower       upper
         <char> <int>      <num>      <num>       <num>       <num>
 1: alpha[42,1]     1  0.2606420 0.10556698  0.04981557  0.46422542
 2: alpha[42,2]     2 -0.5771981 0.09121942 -0.74218424 -0.38698439
 3:  gamma[5,1]     1  0.3242944 0.11039502  0.11060858  0.54541759
 4:  gamma[9,1]     1 -0.2570928 0.11450432 -0.47982937 -0.03620060
 5: gamma[23,1]     1  0.1970185 0.10900929 -0.02021628  0.40359936
 6: gamma[25,1]     1  0.5053186 0.09863274  0.30554315  0.68713432
 7:  gamma[5,2]     2 -0.1576644 0.11622023 -0.38146792  0.07044139
 8:  gamma[9,2]     2 -0.2529766 0.11799725 -0.47516620 -0.01787913
 9: gamma[23,2]     2  0.4733978 0.10064949  0.27783947  0.66510093
10: gamma[25,2]     2 -0.1322218 0.11076333 -0.34501705  0.08840428

On the first term the environment scores agree in sign and size with the published values (0.288, -0.277, 0.278 and 0.459 for environments 5, 9, 23 and 25; here 0.324, -0.257, 0.197, 0.505). Terms beyond the first are weakly identified when 11 terms of similar size are fitted: their order and orientation can differ between analyses.

6 Figure 4: the biplot

bp <-
  bayes_ammi_biplot(
      fit           = fm
    , burnin        = 0
    , thin          = 1
    , pb            = c(0.10, 0.05)
    , plot_stable   = FALSE
    , plot_unstable = TRUE
    , ncolors       = 5
    , .which        = "both"
    , .grid         = 100
    )
bp$biplot

7 References

Perez-Elizalde, S., Jarquin, D. and Crossa, J. (2012). A general Bayesian estimation method of linear-bilinear models applied to plant breeding trials with genotype x environment interaction. Journal of Agricultural, Biological, and Environmental Statistics, 17, 15–37. doi:10.1007/s13253-011-0063-9

Crossa, J., Perez-Elizalde, S., Jarquin, D., Cotes, J. M., Viele, K., Liu, G. and Cornelius, P. L. (2011). Bayesian estimation of the additive main effects and multiplicative interaction model. Crop Science, 51(4), 1458–1469. doi:10.2135/cropsci2010.06.0343