Updates on genomic selection
Day 2: Genomic selection under the genotype-by-environment interaction
Data Science for Plant Breeding Lab
Piracicaba, September 2nd
Following Grattapaglia (2022):
Theory from Population and Quantitative Genetics
Practical factors
Effective population size
Size and composition of the training population
Size and composition of the training population
Size and composition of the training population
Trait heritability
Historical data
A model trained in one environment may not work in another. An “environment” can be a location, a season, a year or even a different management.
\[ \Delta G = \frac{i \times \color{red}{r_A} \times \sigma_A}{L \times C} \]
Real life: unbalanced data
library(ggpubr)
library(tidyverse)
dat = readRDS("../Data/G2F.RDS")
geno_per_trial = as.data.frame(table(dat$gen, dat$loc)) |>
mutate(Freq = ifelse(Freq != 0, 1, 0))
geno_per_year = as.data.frame(table(dat$gen, dat$year)) |>
mutate(Freq = ifelse(Freq != 0, 1, 0))
ggarrange(
ggplot(data = geno_per_year, aes(
x = Var2, y = Var1, fill = as.factor(Freq)
)) +
geom_tile() +
theme_minimal() +
theme(
axis.text.y = element_blank(),
legend.title = element_blank(),
legend.position = 'top'
) +
scale_fill_manual(
values = c('#b2bc63', '#10342d'),
labels = c("Abscent", "Present")
) +
scale_alpha_manual(
values = c(.4, 1),
labels = c("Abscent", "Present")
) +
labs(x = "Year", y = "Hybrid"),
ggplot(data = geno_per_trial, aes(
x = Var2, y = Var1, fill = as.factor(Freq)
)) +
geom_tile() +
theme_minimal() +
theme(
axis.text.y = element_blank(),
legend.title = element_blank(),
legend.position = 'top',
axis.text.x = element_text(
angle = 90,
vjust = .5,
hjust = 1
)
) +
scale_fill_manual(
values = c('#b2bc63', '#10342d'),
labels = c("Abscent", "Present")
) +
scale_alpha_manual(
values = c(.5, 1),
labels = c("Abscent", "Present")
) +
labs(x = "Location", y = "Hybrid"),
common.legend = TRUE,
labels = "AUTO",
nrow = 1
)Sparse-testing
Sparse-testing
Sparse-testing
Leveraging historical data
Leveraging historical data
Leveraging historical data
Defining breeding zones
\[ \boldsymbol y = \boldsymbol X \boldsymbol e + \boldsymbol Z_1 \boldsymbol g + \boldsymbol Z_2 \boldsymbol {ge} + \boldsymbol \varepsilon \]
\[ \begin{bmatrix} \boldsymbol{X}^\prime \boldsymbol X & \boldsymbol X^\prime \boldsymbol Z_1 & \boldsymbol X^\prime \boldsymbol Z_2 \\ \boldsymbol Z_1^\prime \boldsymbol X & \left(\boldsymbol Z_1^\prime \boldsymbol Z_1 + \lambda_1 \boldsymbol{G}^{-1} \right) & \boldsymbol Z_1^\prime\boldsymbol Z_2 \\ \boldsymbol Z_2^\prime \boldsymbol X & \boldsymbol Z^\prime_2\boldsymbol Z_1 & \left(\boldsymbol Z_2^\prime \boldsymbol Z_2 + \lambda_2 \boldsymbol{G}^{-1} \right) \end{bmatrix} \begin{bmatrix} \boldsymbol e \\ \boldsymbol g \\ \boldsymbol {ge} \end{bmatrix} = \begin{bmatrix} \boldsymbol X^\prime \boldsymbol y \\ \boldsymbol Z_1^\prime \boldsymbol y \\ \boldsymbol Z_2^\prime \boldsymbol y \end{bmatrix} \]
Numerator relationship matrix
\[ r_{ii^\prime} = \frac{a_{ii^\prime}}{\sqrt{\left(1 + F_i\right)\left(1 + F_{i^\prime}\right)}} \]
\[ a_{ii^\prime} \begin{cases} \mbox{Half-siblings} \to \frac{1}{4} \\ \mbox{Full siblings} \to \frac{1}{2} \\ \mbox{Parent-offspring} \to \frac{1}{2} \end{cases} \]
Numerator relationship matrix: Average (expected) relationship
Genomic relationship matrix
\[ \boldsymbol{G} = \frac{\boldsymbol{\dot{W}}\boldsymbol{\dot{W}}^\prime}{2\sum_m p_m \left(1-p_m\right)} \]
Genomic relationship matrix: Realized relationship
Reaction norm model via RKHS (Reproducing Kernel Hilbert Space)
\[ \bar{\boldsymbol y} = \boldsymbol 1 \mu + \boldsymbol X \boldsymbol e + \boldsymbol Z_1 \boldsymbol g + \boldsymbol Z_2 \boldsymbol {ge} + \boldsymbol \varepsilon \]
CV1: Ability to predict untested individuals. The genetic covariance between relatives in the sole source of information (more challenging)
CV2: Sparse-testing scenario. There are two sources of information in this case: Covariance between relatives and the individual’s performance in tested environments
'data.frame': 85949 obs. of 7 variables:
$ gen : chr "B37/C103" "B37/H95" "B73/MO17" "B73/PHG35" ...
$ year : int 2014 2014 2014 2014 2014 2014 2014 2014 2014 2014 ...
$ loc : chr "GAH1" "GAH1" "GAH1" "GAH1" ...
$ env : chr "GAH1_2014" "GAH1_2014" "GAH1_2014" "GAH1_2014" ...
$ blue : num 4.69 5.98 6.29 9.73 8.05 ...
$ std.error: num 0.828 0.828 0.828 0.828 0.828 ...
$ wt : num 1.91 1.91 1.91 1.91 1.91 ...
ggplot(data = as.data.frame(table(dat$gen, dat$env)),
aes(x = Var2, y = Var1, fill = as.factor(Freq))) +
geom_tile(aes(alpha = as.factor(Freq))) +
theme_minimal() +
theme(axis.text = element_blank(), legend.title = element_blank(),
legend.position = 'top') +
scale_fill_manual(values = c('#b2bc63','#10342d'), labels = c("Abscent", "Present")) +
scale_alpha_manual(values = c(.6, 1), labels = c("Abscent", "Present")) +
labs(x = "Environment (Year-Location combination)", y = "Hybrid") int [1:5899, 1:2105] 1 0 0 1 1 1 1 0 0 0 ...
- attr(*, "dimnames")=List of 2
..$ : chr [1:5899] "01CSI6/LH287" "01DIB2/LH287" "01DIB2/PHP02" "2369/DK3IIH6" ...
..$ : chr [1:2105] "S1_1007742" "S1_1020677" "S1_2018002" "S1_2275970" ...
[1] FALSE
Filtering for didactic purposes!
dat = droplevels(dat[which(dat$year > 2021 & dat$loc %in% c("GAH1","IAH1","IAH2","ILH1", "INH1", "MNH1", "MOH1", "MOH2")),])
dat = dat[which(dat$gen %in% rownames(geno.code)),]
set.seed(7)
dat = dat[which(dat$gen %in% sample(unique(dat$gen),150)),]
geno.code = geno.code[which(rownames(geno.code) %in% dat$gen),]
all(unique(dat$gen) %in% rownames(geno.code))[1] TRUE
Working dataset
ggplot(data = dat, aes(
x = reorder(env, blue),
y = reorder(gen, blue),
fill = blue
)) +
geom_tile() +
theme_minimal() +
theme(axis.text.y = element_blank(), axis.text.x = element_text(angle = 90),
legend.position = "top", legend.title = element_blank()) +
scale_fill_viridis_c(option = "inferno") +
labs(x = paste("Environments: ", length(unique(dat$env))),
y = paste("Hybrid: ", length(unique(dat$gen))))\[ \boldsymbol{G} = \frac{\boldsymbol{\dot{W}}\boldsymbol{\dot{W}}^\prime}{2\sum_m p_m \left(1-p_m\right)} \]
Initial data:
Number of Individuals: 150
Number of Markers: 2105
Missing data check:
Total SNPs: 2105
0 SNPs dropped due to missing data threshold of 0.5
Total of: 2105 SNPs
MAF check:
No SNPs with MAF below 0
Heterozigosity data check:
No SNPs with heterozygosity, missing threshold of = 0
Summary check:
Initial: 2105 SNPs
Final: 2105 SNPs ( 0 SNPs removed)
Completed! Time = 0.34 seconds
library(plotly)
pc = prcomp(Gmat)
pc.df = rbind(
as.data.frame(pc$rotation) |>
rownames_to_column("ID") |>
mutate(comp = "load")
)
plot_ly(
pc.df,
x = ~ PC1,
y = ~ PC2,
z = ~ PC3
) |> add_markers(
text = ~ paste0("Hybrid: ", ID),
hoverinfo = "text",
marker = list(color = '#b2bc63', opacity = .62)
) |> layout(scene = list(
xaxis = list(
title = paste0("PC1 (", round(pc$sdev[1]^2/sum(pc$sdev^2)*100,2), "%)"),
showgrid = TRUE,
range = c(min(c(
range(pc.df$pc1), range(pc.df$pc2), range(pc.df$pc3)
)), max(c(
range(pc.df$pc1), range(pc.df$pc2), range(pc.df$pc3)
)))
),
yaxis = list(
title = paste0("PC2 (", round(pc$sdev[2]^2/sum(pc$sdev^2)*100,2), "%)"),
showgrid = TRUE,
range = c(min(c(
range(pc.df$pc1), range(pc.df$pc2), range(pc.df$pc3)
)), max(c(
range(pc.df$pc1), range(pc.df$pc2), range(pc.df$pc3)
)))
),
zaxis = list(
title = paste0("PC3 (", round(pc$sdev[3]^2/sum(pc$sdev^2)*100,2), "%)"),
showgrid = TRUE,
range = c(min(c(
range(pc.df$pc1), range(pc.df$pc2), range(pc.df$pc3)
)), max(c(
range(pc.df$pc1), range(pc.df$pc2), range(pc.df$pc3)
)))
)
))Reaction norm model via RKHS (Reproducing Kernel Hilbert Space)
\[ \bar{\boldsymbol y} = \boldsymbol 1 \mu + \boldsymbol Z_e \boldsymbol e + \boldsymbol Z_g \boldsymbol g + \boldsymbol Z_{ge} \boldsymbol {ge} + \boldsymbol \varepsilon \]
Expanding the data frame
Expanding the data frame
ggplot(data = dat, aes(
x = reorder(env, blue),
y = reorder(gen, blue),
fill = blue
)) +
geom_tile() +
theme_minimal() +
theme(axis.text.y = element_blank(), axis.text.x = element_text(angle = 90),
legend.position = "top", legend.title = element_blank(),
text = element_text(size = 18)) +
scale_fill_viridis_c(option = "inferno", na.value = "lightgrey") +
labs(x = paste("Environments: ", length(unique(dat$env))),
y = paste("Hybrid: ", length(unique(dat$gen))))Incidence matrices
B37/H95 B73/TX779 BGEM-0039-N/LH244 BGEM-0063-N/LH244
B37/H95 1 0 0 0
B73/TX779 0 1 0 0
BGEM-0039-N/LH244 0 0 1 0
BGEM-0063-N/LH244 0 0 0 1
GEMN-0096/LH244 0 0 0 0
GEMN-0096/LH244
B37/H95 0
B73/TX779 0
BGEM-0039-N/LH244 0
BGEM-0063-N/LH244 0
GEMN-0096/LH244 1
Incidence matrices
\[ \boldsymbol K_g = \boldsymbol Z_g \boldsymbol G \boldsymbol Z_g^\prime \]
Expanded \(\boldsymbol G\) (for three environments)
aux = do.call(c, lapply(split(dat, dat$env), nrow))
submat = ZGZ[1:sum(aux[1:3]),1:sum(aux[1:3])]
col_fun = colorRamp2(c(min(submat), 0, max(submat)), c("blue4", "white", "green4"))
Heatmap(
submat,
show_row_dend = FALSE,
show_row_names = FALSE,
show_column_dend = FALSE,
show_column_names = FALSE,
column_split = rep(names(aux)[1:3], aux[1:3]),
row_split = rep(names(aux)[1:3], aux[1:3]),
col = col_fun,
show_heatmap_legend = FALSE,
border = TRUE,
border_gp = gpar(col = "black", lty = 2)
)\[ \boldsymbol K_e = \boldsymbol Z_e \boldsymbol Z_e^\prime \]
Only 1s and 0s!
submat = ZEZ[1:sum(aux[1:4]), 1:sum(aux[1:4])]
col_fun = colorRamp2(c(min(submat), 0, max(submat)), c("blue4", "white", "green4"))
Heatmap(
submat,
show_row_dend = FALSE,
show_row_names = FALSE,
show_column_dend = FALSE,
show_column_names = FALSE,
column_split = rep(names(aux)[1:4], aux[1:4]),
row_split = rep(names(aux)[1:4], aux[1:4]),
col = col_fun,
show_heatmap_legend = FALSE,
border = TRUE,
border_gp = gpar(col = "black", lty = 2)
)\[ \boldsymbol K_{ge} = \boldsymbol K_g \odot \boldsymbol K_e \]
submat = GEI[1:sum(aux[1:5]),1:sum(aux[1:5])]
col_fun = colorRamp2(c(min(submat), 0, max(submat)), c("blue4", "white", "green4"))
Heatmap(
submat,
show_row_dend = FALSE,
show_row_names = FALSE,
show_column_dend = FALSE,
show_column_names = FALSE,
column_split = rep(names(aux)[1:5], aux[1:5]),
row_split = rep(names(aux)[1:5], aux[1:5]),
col = col_fun,
show_heatmap_legend = FALSE,
border = TRUE,
border_gp = gpar(col = "black", lty = 2),
row_title_gp = gpar(fontsize = 8)
)Eigendecomposition (efficient computation)
\[ \begin{gather} \boldsymbol K_{ge} = \boldsymbol V_{ge} \boldsymbol D_{ge} \boldsymbol V_{ge} \\ \boldsymbol K_{g} = \boldsymbol V_{g} \boldsymbol D_{g} \boldsymbol V_{g} \end{gather} \]
Lesser number of iterations required (than BayesB)
library(BGLR)
ETA = list(
env = list(X = ZE, model = 'FIXED'),
hyb = list(V = ZGZ$vectors, d = ZGZ$values, model = 'RKHS'),
gei = list(V = GEI$vectors, d = GEI$values, model = 'RKHS')
)
model1 = BGLR(y = dat$blue, ETA = ETA, nIter = 12000, burnIn = 2000,
thin = 10, verbose = TRUE, saveAt = "complete_met1_")Reparameterized model: Cholesky decomposition of \(\boldsymbol G\)
\[ \boldsymbol G = \boldsymbol L \boldsymbol L^\prime \]
\[ \begin{gather} \boldsymbol X_g = \boldsymbol Z_g \times \boldsymbol L \\ \boldsymbol X_{ge} = \boldsymbol X_g:\boldsymbol Z_e \end{gather} \]
\(\boldsymbol X_g\):
submat = X_g[1:sum(aux[1:2]),]
col_fun = colorRamp2(c(min(submat), 0, max(submat)), c("blue4", "white", "green4"))
Heatmap(
submat,
show_row_dend = FALSE,
show_row_names = FALSE,
show_column_dend = FALSE,
show_column_names = FALSE,
row_order = 1:nrow(submat),
column_order = colnames(submat),
col = col_fun,
# row_split = rep(names(aux)[1:2], aux[1:2]),
show_heatmap_legend = FALSE
)\(\boldsymbol X_ge\):
Model parameters
varE varG varGE model
1 1.882919 1.553343 1.697239 RKHS
2 1.876174 1.724512 1.703228 CHOL (BRR)
Model parameters
modparam |> group_by(model) |>
mutate(varT = varE + varG + varGE,
PvE = varE/varT,
PvG = varG/varT,
PvGE = varGE/varT) |> relocate(model, .before = varE) |>
pivot_longer(varE:PvGE) |> filter(!grepl("var", name)) |>
ggplot(aes(x = model, y = value)) +
geom_col(aes(fill = name), color = "black") +
theme_bw() +
labs(x = "Model", y = "Percentage from total variance") +
scale_y_continuous(labels = scales::percent) +
scale_fill_viridis_d(option="mako", labels = c("varE", "varG", "varGEI")) +
theme(text = element_text(size = 18), legend.position = "top",
legend.title = element_blank())Predictions
Convergence
library(coda)
trace_varE = read.table("../Saves/dat/complete_met2_varE.dat")[,1]
trace_varG = read.table("../Saves/dat/complete_met2_ETA_hyb_varU.dat")[,1]
trace_varGEI = read.table("../Saves/dat/complete_met2_ETA_gei_varU.dat")[,1]
varE_chain = mcmc(trace_varE[201:length(trace_varE)])
varG_chain = mcmc(trace_varG[201:length(trace_varG)])
varGEI_chain = mcmc(trace_varGEI[201:length(trace_varGEI)])
plot(varE_chain)Convergence
CV2: Sparse-testing
CV2: Sparse-testing
cv2 = lapply(cvdata, function(x){
res.list = list()
for (i in unique(x$set)) {
yNA = x$blue
yNA[x$set == i] = NA
mod_cv = BGLR(y = yNA, ETA = ETA2, nIter = 8000, burnIn = 1000,
thin = 10, verbose = FALSE, saveAt = "modCV")
unlink(list.files(pattern = "modCV"))
res.list[[i]] = data.frame(
gen = x$gen,
env = x$env,
blue = x$blue,
set = x$set,
yNA = yNA,
yhat = mod_cv$yHat
) |> filter(set == i)
}
res.list
})
cv2 = lapply(cv2, function(x) do.call(rbind, x))CV1: Untested genotypes
sets = list()
i = 1
repeat{
set.seed(7 * i)
sets[[i]] = sample(rep(1:nfolds, length.out = nlevels(dat$gen)))
i = i + 1
if(i > nrept) break
}
cvdata = lapply(sets, function(x){
cvdata = dat
aux = data.frame(gen = levels(dat$gen), set = x)
cvdata$set = aux$set[match(cvdata$gen, aux$gen)]
return(cvdata)
})
for (i in 1:length(cvdata)) cvdata[[i]]$rept = iCV1: Untested genotypes
cv1 = lapply(cvdata, function(x){
res.list = list()
for (i in unique(x$set)) {
yNA = x$blue
yNA[x$set == i] = NA
mod_cv = BGLR(y = yNA, ETA = ETA2, nIter = 8000, burnIn = 1000,
thin = 10, verbose = FALSE, saveAt = "modCV")
unlink(list.files(pattern = "modCV"))
res.list[[i]] = data.frame(
gen = x$gen,
env = x$env,
blue = x$blue,
set = x$set,
yNA = yNA,
yhat = mod_cv$yHat
) |> filter(set == i)
}
res.list
})
cv1 = lapply(cv1, function(x) do.call(rbind, x))[[1]]
env rmspe pa
1 GAH1_2022 1.889566 0.1702812
2 IAH1_2022 2.022620 0.4196013
3 IAH2_2022 3.367848 0.3187834
4 ILH1_2022 1.874160 0.2719688
5 INH1_2022 1.423681 0.4246822
6 MNH1_2022 1.558176 0.4690019
7 MOH2_2022 1.650287 0.2446381
8 GAH1_2023 2.035345 0.2008071
9 IAH1_2023 1.836036 0.6045529
10 IAH2_2023 1.221760 0.6056442
11 ILH1_2023 1.404764 0.4389203
12 INH1_2023 1.892373 0.3624826
13 MNH1_2023 1.519305 0.5680988
14 MOH1_2023 1.388520 0.1090614
15 MOH2_2023 1.346523 0.3344103
[[2]]
env rmspe pa
1 GAH1_2022 1.895644 0.1692424
2 IAH1_2022 2.022137 0.4211831
3 IAH2_2022 3.348890 0.3302070
4 ILH1_2022 1.802512 0.3632502
5 INH1_2022 1.467618 0.3716514
6 MNH1_2022 1.646410 0.3707182
7 MOH2_2022 1.605652 0.3188448
8 GAH1_2023 1.968891 0.2829812
9 IAH1_2023 1.820997 0.6173261
10 IAH2_2023 1.244461 0.5841689
11 ILH1_2023 1.412772 0.4303447
12 INH1_2023 1.892635 0.3607798
13 MNH1_2023 1.566753 0.5314768
14 MOH1_2023 1.360501 0.1643439
15 MOH2_2023 1.353044 0.3290723
[[3]]
env rmspe pa
1 GAH1_2022 1.882118 0.1596959
2 IAH1_2022 1.960602 0.4768718
3 IAH2_2022 3.402141 0.2905243
4 ILH1_2022 1.841893 0.3115065
5 INH1_2022 1.523762 0.2920739
6 MNH1_2022 1.535121 0.4934392
7 MOH2_2022 1.655805 0.2327191
8 GAH1_2023 2.024429 0.2070284
9 IAH1_2023 1.835144 0.6052883
10 IAH2_2023 1.195456 0.6312664
11 ILH1_2023 1.336070 0.5263628
12 INH1_2023 1.837789 0.4195306
13 MNH1_2023 1.497860 0.5918761
14 MOH1_2023 1.348625 0.1581148
15 MOH2_2023 1.292592 0.4124761
[[4]]
env rmspe pa
1 GAH1_2022 1.858716 0.2065210
2 IAH1_2022 2.048789 0.3957298
3 IAH2_2022 3.484799 0.2365388
4 ILH1_2022 1.891632 0.2530135
5 INH1_2022 1.533387 0.2818449
6 MNH1_2022 1.662090 0.3516716
7 MOH2_2022 1.665324 0.2225250
8 GAH1_2023 1.999532 0.2455527
9 IAH1_2023 1.924328 0.5472414
10 IAH2_2023 1.298657 0.5312214
11 ILH1_2023 1.454470 0.3739427
12 INH1_2023 1.965409 0.2801419
13 MNH1_2023 1.618175 0.4766807
14 MOH1_2023 1.400039 0.1025656
15 MOH2_2023 1.406617 0.2493828
[[5]]
env rmspe pa
1 GAH1_2022 1.873404 0.1869904
2 IAH1_2022 2.031339 0.4127986
3 IAH2_2022 3.371061 0.3154021
4 ILH1_2022 1.794050 0.3727625
5 INH1_2022 1.453547 0.3866245
6 MNH1_2022 1.517166 0.5110332
7 MOH2_2022 1.632968 0.2727572
8 GAH1_2023 2.038913 0.1886679
9 IAH1_2023 1.831827 0.6083938
10 IAH2_2023 1.201414 0.6253156
11 ILH1_2023 1.418105 0.4232666
12 INH1_2023 1.858152 0.3986870
13 MNH1_2023 1.449322 0.6340561
14 MOH1_2023 1.319553 0.2265163
15 MOH2_2023 1.318570 0.3765377
rmspe pa rept CV
1 1.762064 0.3695290 1 CV1
2 1.760595 0.3763727 2 CV1
3 1.744627 0.3872516 3 CV1
4 1.814131 0.3169716 4 CV1
5 1.740626 0.3959873 5 CV1
[[1]]
env rmspe pa
1 GAH1_2022 1.879606 0.2662937
2 IAH1_2022 1.797687 0.5931229
3 IAH2_2022 3.210433 0.4251466
4 ILH1_2022 1.725585 0.4573075
5 INH1_2022 1.177796 0.6625441
6 MNH1_2022 1.479689 0.5490231
7 MOH2_2022 1.530060 0.4449176
8 GAH1_2023 2.058755 0.2433487
9 IAH1_2023 1.539022 0.7588185
10 IAH2_2023 1.035859 0.7375820
11 ILH1_2023 1.244886 0.6049751
12 INH1_2023 1.613326 0.6118256
13 MNH1_2023 1.279705 0.7223321
14 MOH1_2023 1.256384 0.4034762
15 MOH2_2023 1.131159 0.6052655
[[2]]
env rmspe pa
1 GAH1_2022 1.850584 0.2928406
2 IAH1_2022 1.737497 0.6325008
3 IAH2_2022 3.343739 0.3347174
4 ILH1_2022 1.740162 0.4444828
5 INH1_2022 1.202679 0.6439494
6 MNH1_2022 1.415093 0.5985186
7 MOH2_2022 1.591965 0.3748018
8 GAH1_2023 2.028339 0.2760836
9 IAH1_2023 1.528469 0.7627030
10 IAH2_2023 1.024830 0.7437002
11 ILH1_2023 1.208967 0.6339923
12 INH1_2023 1.607658 0.6158269
13 MNH1_2023 1.317938 0.7009847
14 MOH1_2023 1.250440 0.4028758
15 MOH2_2023 1.133991 0.6028341
[[3]]
env rmspe pa
1 GAH1_2022 1.865127 0.2793878
2 IAH1_2022 1.765478 0.6163797
3 IAH2_2022 3.343894 0.3345007
4 ILH1_2022 1.700967 0.4806699
5 INH1_2022 1.166414 0.6718908
6 MNH1_2022 1.421570 0.5929087
7 MOH2_2022 1.518983 0.4505503
8 GAH1_2023 1.980359 0.3149610
9 IAH1_2023 1.534773 0.7588277
10 IAH2_2023 1.018471 0.7472612
11 ILH1_2023 1.238987 0.6119061
12 INH1_2023 1.645343 0.5850448
13 MNH1_2023 1.294980 0.7139840
14 MOH1_2023 1.244532 0.4129931
15 MOH2_2023 1.121777 0.6125460
[[4]]
env rmspe pa
1 GAH1_2022 1.852358 0.2850538
2 IAH1_2022 1.768035 0.6125090
3 IAH2_2022 3.306263 0.3618793
4 ILH1_2022 1.671418 0.5061276
5 INH1_2022 1.191953 0.6521207
6 MNH1_2022 1.449059 0.5709491
7 MOH2_2022 1.545193 0.4249735
8 GAH1_2023 2.033443 0.2636737
9 IAH1_2023 1.556104 0.7556200
10 IAH2_2023 1.033698 0.7381824
11 ILH1_2023 1.223525 0.6227211
12 INH1_2023 1.524027 0.6711545
13 MNH1_2023 1.320506 0.7034818
14 MOH1_2023 1.275118 0.3930340
15 MOH2_2023 1.110774 0.6239383
[[5]]
env rmspe pa
1 GAH1_2022 1.845270 0.2991219
2 IAH1_2022 1.793866 0.5942029
3 IAH2_2022 3.375256 0.3146511
4 ILH1_2022 1.730234 0.4577725
5 INH1_2022 1.170492 0.6687173
6 MNH1_2022 1.460144 0.5639850
7 MOH2_2022 1.545673 0.4246391
8 GAH1_2023 2.019055 0.2711392
9 IAH1_2023 1.564224 0.7458028
10 IAH2_2023 1.012800 0.7515672
11 ILH1_2023 1.257817 0.5936511
12 INH1_2023 1.566635 0.6440214
13 MNH1_2023 1.303418 0.7095823
14 MOH1_2023 1.251500 0.4103725
15 MOH2_2023 1.113108 0.6220204
rmspe pa rept CV
1 1.597330 0.5390653 1 CV2
2 1.598823 0.5373875 2 CV2
3 1.590777 0.5455875 3 CV2
4 1.590765 0.5456946 4 CV2
5 1.600633 0.5380831 5 CV2
rbind(res_cv1_mean, res_cv2_mean) |>
pivot_longer(rmspe:pa) |>
ggplot(aes(x = CV, y = value)) +
facet_wrap(.~name, scales = "free_y", labeller = labeller(.cols = c("pa" = "Predictive ability", "rmspe" = "RMSPE")))+
geom_boxplot(fill = "#b2bc63") +
theme_bw() +
theme(axis.title.y = element_blank(), text = element_text(size = 18))for (i in 1:length(res_cv1)){
res_cv1[[i]]$rept = i
res_cv1[[i]]$CV = "CV1"
}
for (i in 1:length(res_cv2)){
res_cv2[[i]]$rept = i
res_cv2[[i]]$CV = "CV2"
}
rbind(
do.call(rbind, res_cv1),
do.call(rbind, res_cv2)
) |> pivot_longer(rmspe:pa) |>
ggplot(aes(x = env, y = value)) +
# facet_wrap(.~name, scales = "free_y", labeller = labeller(.cols = c("pa" = "Predictive ability", "rmspe" = "RMSPE"))) +
facet_grid(name~CV, scales = 'free_y',
labeller = labeller(.rows = c("pa" = "Predictive ability",
"rmspe" = "RMSPE")))+
theme_bw() +
theme(axis.title.y = element_blank(), text = element_text(size = 14),
axis.text.x = element_text(angle = 90, vjust = .5, hjust = 1)) +
geom_boxplot(fill = "#b2bc63")