Nothing
#' S3 class stability
#'
#' Function for creating objects of S3 class stability.\cr
#' \code{\link{print}}, \code{\link{summary}}, \code{\link{plot}} and
#' \code{\link{report}} methods are available.
#'
#' @param superiority A data.frame containing values for the
#' cultivar-superiority measure of Lin and Binns.
#' @param static A data.frame containing values for Shukla's stability variance.
#' @param wricke A data.frame containing values for Wricke's ecovalence.
#' @param trait A character string indicating the trait that has been analyzed.
#'
#' @name stability
NULL
#' @rdname stability
#' @keywords internal
createStability <- function(superiority = NULL,
static = NULL,
wricke = NULL,
TD,
trait) {
stability <- structure(list(superiority = superiority,
static = static,
wricke = wricke,
TD = TD,
trait = trait),
class = "stability")
attr(stability, which = "timestamp") <- Sys.time()
return(stability)
}
#' @export
print.stability <- function(x,
...,
pctGeno = 10) {
if (!is.null(x$superiority)) {
cat("\nCultivar-superiority measure (Top", pctGeno, "% genotypes)\n")
print(x$superiority[1:(ceiling(nrow(x$superiority) / 100 * pctGeno)), ],
row.names = FALSE)
}
if (!is.null(x$static)) {
cat("\nStatic stability (Top", pctGeno, "% genotypes)\n")
print(x$static[1:(ceiling(nrow(x$static) / 100 * pctGeno)), ],
row.names = FALSE)
}
if (!is.null(x$wricke)) {
cat("\nWricke's ecovalence (Top", pctGeno, "% genotypes)\n")
print(x$wricke[1:(ceiling(nrow(x$wricke) / 100 * pctGeno)), ],
row.names = FALSE)
}
}
#' @export
summary.stability <- function(object,
...) {
print(object, ...)
}
#' Plot function for class stability
#'
#' Function for creating scatter plots of the square roots of the computed
#' stability measures against the means.
#'
#' @param x An object of class stability.
#' @param ... Not used.
#' @param colorGenoBy A character string indicating a column in the \code{TD}
#' used as input for the stability analysis by which the genotypes should be
#' colored. If \code{NULL} all genotypes will be colored black.
#' @param colGeno A character vector with plot colors for the genotypes. A
#' single color when \code{colorGenoBy = NULL}, a vector of colors otherwise.
#' @param title A character string used a title for the plot.
#' @param output Should the plot be output to the current device? If
#' \code{FALSE} only a list of ggplot objects is invisibly returned.
#'
#' @return A list of ggplot object is invisibly returned.
#'
#' @examples
#' ## Compute three stability measures for TDMaize.
#' geStab <- gxeStability(TD = TDMaize, trait = "yld")
#'
#' ## Create scatter plots of the computed stability measures against the means.
#' plot(geStab)
#'
#' @family stability
#'
#' @importFrom grDevices topo.colors
#' @export
plot.stability <- function(x,
...,
colorGenoBy = NULL,
colGeno = NULL,
title = paste("Stability coefficients for", x$trait),
output = TRUE) {
chkChar(title, len = 1, null = FALSE)
TDTot <- do.call(rbind, x$TD)
if (!is.null(colorGenoBy)) {
chkCol(colorGenoBy, TDTot)
}
chkChar(colGeno)
genoDat <- unique(TDTot[c("genotype", colorGenoBy)])
if (!is.null(colorGenoBy)) {
if (!is.factor(genoDat[[colorGenoBy]])) {
genoDat[[colorGenoBy]] <- as.factor(genoDat[[colorGenoBy]])
}
genoDat <- genoDat[order(genoDat[[colorGenoBy]]), ]
} else {
genoDat[[".colorGenoBy"]] <- factor(1)
colorGenoBy <- ".colorGenoBy"
}
nColGeno <- nlevels(genoDat[[colorGenoBy]])
if (length(colGeno) == 0) {
## Defaults to black for one color for genotypes.
## For more than one colors from statgen.genoColors are used.
## Fall back to topo.colors if number of colors in option is too small.
if (nColGeno == 1) {
colGeno <- "black"
} else if (length(getOption("statgen.genoColors")) >= nColGeno) {
colGeno <- getOption("statgen.genoColors")[1:nColGeno]
} else {
colGeno <- topo.colors(nColGeno)
}
} else {
nColGenoArg <- length(colGeno)
if (nColGenoArg != nColGeno) {
stop("Number of colors provided doesn't match number of genotype groups:",
"\n", nColGenoArg, " colors provided, ", nColGeno,
" groups in data.\n")
}
}
plots <- vector(mode = "list")
if (!is.null(x$superiority)) {
## Create superiority plot.
supDat <- merge(x$superiority, genoDat, by.x = "Genotype", by.y = "genotype")
plots$p1 <- ggplot2::ggplot(data = supDat,
ggplot2::aes(x = .data[["Mean"]],
y = sqrt(.data[["Superiority"]]),
color = .data[[colorGenoBy]])) +
ggplot2::geom_point() +
ggplot2::scale_color_manual(values = colGeno) +
ggplot2::labs(x = "Mean", y = "Square root of\n Cultivar superiority")
}
if (!is.null(x$static)) {
## Create static plot.
statDat <- merge(x$static, genoDat, by.x = "Genotype", by.y = "genotype")
plots$p2 <- ggplot2::ggplot(data = statDat,
ggplot2::aes(x = "Mean",
y = sqrt(.data[["Static"]]),
color = .data[[colorGenoBy]])) +
ggplot2::geom_point() +
ggplot2::scale_color_manual(values = colGeno) +
ggplot2::labs(x = "Mean", y = "Square root of\n Static stability")
}
if (!is.null(x$wricke)) {
## Create Wricke plot.
wrickeDat <- merge(x$wricke, genoDat, by.x = "Genotype", by.y = "genotype")
plots$p3 <- ggplot2::ggplot(data = wrickeDat,
ggplot2::aes(x = "Mean",
y = sqrt(.data[["Wricke"]]),
color = .data[[colorGenoBy]])) +
ggplot2::geom_point() +
ggplot2::scale_color_manual(values = colGeno) +
ggplot2::labs(x = "Mean", y = "Square root of\n Wricke's ecovalence")
}
## Construct legend.
if (colorGenoBy != ".colorGenoBy") {
## Build plot to extract legend.
## Legend is always the same for all plots, take it from the first plot.
p1Gtable <- ggplot2::ggplot_gtable(ggplot2::ggplot_build(plots[[1]]))
legendPos <- sapply(X = p1Gtable$grobs, FUN = `[[`, "name") == "guide-box"
legend <- p1Gtable$grobs[[which(legendPos)]]
} else {
legend <- NULL
}
## Now remove the legend from all the plots.
for (i in seq_along(plots)) {
plots[[i]] <- plots[[i]] + ggplot2::theme(legend.position = "none")
}
if (length(plots) == 3) {
## Create empty plot for bottom right grid position.
plots$p4 <- ggplot2::ggplot() +
ggplot2::theme(panel.background = ggplot2::element_blank())
}
## Convert plots to grob for outlining of axes.
plotsGr <- lapply(X = plots, FUN = ggplot2::ggplotGrob)
if (length(plotsGr) > 1) {
## At least two plots -> 1 row.
tot <- gridExtra::gtable_cbind(plotsGr[[1]], plotsGr[[2]])
} else {
## Only 1 plot to be made.
tot <- plotsGr[[1]]
}
if (length(plotsGr) > 2) {
## 3 Plots, so empty plot has been created to make 4 plots.
## First create second row then add to first row.
r2 <- gridExtra::gtable_cbind(plotsGr[[3]], plotsGr[[4]])
tot <- gridExtra::gtable_rbind(tot, r2)
}
if (output) {
## grid.arrange automatically plots the results.
tot <- gridExtra::grid.arrange(tot, right = legend, top = title)
}
invisible(plots)
}
#' Report method for class stability
#'
#' A pdf report will be created containing a summary of an object of class
#' stability. Simultaneously the same report will be created as a tex file.
#'
#' @inheritParams report.AMMI
#'
#' @param x An object of class stability.
#'
#' @return A pdf and tex report.
#'
#' @examples
#' ## Compute three stability measures for TDMaize.
#' geStab <- gxeStability(TD = TDMaize, trait = "yld")
#' \donttest{
#' ## Create a .pdf report summarizing the stability measures.
#' report(geStab, outfile = tempfile(fileext = ".pdf"))
#' }
#'
#' @family stability
#'
#' @export
report.stability <- function(x,
...,
outfile = NULL) {
## Checks.
if (nchar(Sys.which("pdflatex")) == 0) {
stop("An installation of LaTeX is required to create a pdf report.\n")
}
createReport(x = x, reportName = "stabilityReport.Rnw",
reportPackage = "statgenGxE", outfile = outfile, ...)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.