From 88409f81a459765c727a25613ca6336b36e4911e Mon Sep 17 00:00:00 2001 From: TuomasBorman Date: Mon, 7 Oct 2024 17:44:32 +0300 Subject: [PATCH] Fix biochecks --- R/plotCCA.R | 483 ++++++++++++++++++++++++----------------------- R/plotLoadings.R | 2 +- man/plotCCA.Rd | 168 +++++++---------- 3 files changed, 316 insertions(+), 337 deletions(-) diff --git a/R/plotCCA.R b/R/plotCCA.R index 8e21543f..6ef26656 100644 --- a/R/plotCCA.R +++ b/R/plotCCA.R @@ -5,79 +5,80 @@ #' for supervised ordination of microbiome data. #' #' @param x a -#' \code{\link[TreeSummarizedExperiment:TreeSummarizedExperiment-constructor]{TreeSummarizedExperiment}} -#' or a matrix of weights. The latter is returned as output from \code{\link[mia:runCCA]{getRDA}}. +#' \code{\link[TreeSummarizedExperiment:TreeSummarizedExperiment-constructor]{TreeSummarizedExperiment}} +#' or a matrix of weights. The latter is returned as output from +#' \code{\link[mia:runCCA]{getRDA}}. #' -#' @param dimred \code{Character scalar} or \code{integer scalar}. Determines the reduced dimension to -#' plot. This is the output of \code{\link[mia:runCCA]{addRDA}} and resides in -#' \code{reducedDim(tse, dimred)}. +#' @param dimred \code{Character scalar} or \code{integer scalar}. Determines +#' the reduced dimension to +#' plot. This is the output of \code{\link[mia:runCCA]{addRDA}} and resides in +#' \code{reducedDim(tse, dimred)}. #' -#' @param add.ellipse One of \code{c(TRUE, FALSE, "fill", "colour", "color")}, -#' indicating whether ellipses should be present, absent, filled or colored. +#' @param ... additional parameters for plotting, inherited from +#' \code{\link[scater:plotReducedDim]{plotReducedDim}}, +#' \code{\link[ggplot2:geom_label]{geom_label}} and +#' \code{\link[ggrepel:geom_label_repel]{geom_label_repel}}. +#' \itemize{ +#' \item \code{add.ellipse}: One of +#' \code{c(TRUE, FALSE, "fill", "colour")}, indicating whether +#' ellipses should be present, absent, filled or colored. #' (default: \code{ellipse.fill = TRUE}) -#' -#' @param ellipse.alpha \code{Numeric scalar}. Between 0 and 1. Adjusts the opacity of ellipses. -#' (Default: \code{0.2}) -#' -#' @param ellipse.linewidth \code{Numeric scalar}. Specifies the size of ellipses. -#' (Default: \code{0.1}) -#' -#' @param ellipse.linetype \code{Integer scalar}. Specifies the style of ellipses. -#' (Default: \code{1}) #' -#' @param confidence.level \code{Numeric scalar}. Between 0 and 1. Adjusts confidence level. -#' (Default: \code{0.95}) -#' -#' @param add.vectors \code{Logical scalar}. Should vectors appear in the plot. -#' (Default: \code{TRUE}) +#' \item \code{ellipse.alpha}: \code{Numeric scalar}. Between 0 and 1. +#' Adjusts the opacity of ellipses. (Default: \code{0.2}) +#' +#' \item \code{ellipse.linewidth}: \code{Numeric scalar}. Specifies the size +#' of ellipses. (Default: \code{0.1}) #' -#' @param vec.size \code{Numeric scalar}. Specifies the size of vectors. -#' (Default: \code{0.5}) +#' \item \code{ellipse.linetype}: \code{Integer scalar}. Specifies the style +#' of ellipses. (Default: \code{1}) #' -#' @param vec.colour \code{Character scalar}. Specifies the colour of vectors. -#' (Default: \code{"black"}) +#' \item \code{confidence.level}: \code{Numeric scalar}. Between 0 and 1. +#' Adjusts confidence level. (Default: \code{0.95}) #' -#' @param vec.color Alias for `vec.colour`. +#' \item \code{add.vectors}: \code{Logical scalar}. Should vectors appear in +#' the plot. (Default: \code{TRUE}) #' -#' @param vec.linetype \code{Integer scalar}. Specifies the style of vector lines. -#' (Default: \code{1}) +#' \item \code{vec.size}: \code{Numeric scalar}. Specifies the size of +#' vectors. (Default: \code{0.5}) #' -#' @param arrow.size \code{Numeric scalar}. Specifies the size of arrows. -#' (defaults: \code{arrow.size = 0.25}) +#' \item \code{vec.colour}: \code{Character scalar}. Specifies the colour of +#' vectors. (Default: \code{"black"}) #' -#' @param label.size \code{Numeric scalar}. Specifies the size of text and labels. -#' (Default: \code{4}) +#' \item \code{vec.linetype}: \code{Integer scalar}. Specifies the style of +#' vector lines. (Default: \code{1}) #' -#' @param label.colour \code{Character scalar}. Specifies the colour of text and labels. -#' (Default: \code{"black"}) +#' \item \code{arrow.size}: \code{Numeric scalar}. Specifies the size of +#' arrows. (Default: \code{arrow.size = 0.25}) #' -#' @param label.color Alias for `label.colour`. +#' \item \code{label.size}: \code{Numeric scalar}. Specifies the size of text +#' and labels. (Default: \code{4}) #' -#' @param sep.group \code{Character scalar}. Specifies the separator used in the labels. -#' (Default: \code{"\U2014"}) -#' -#' @param repl.underscore \code{Character scalar}. Used to replace underscores in the labels. -#' (Default: \code{" "}) +#' \item \code{label.colour}: \code{Character scalar}. Specifies the colour of +#' text and labels. (Default: \code{"black"}) #' -#' @param vec.text \code{Logical scalar}. Should text instead of labels be used to label vectors. -#' (Default: \code{TRUE}) +#' \item \code{sep.group}: \code{Character scalar}. Specifies the separator +#' used in the labels. (Default: \code{"\U2014"}) #' -#' @param repel.labels \code{Logical scalar}. Should labels be repelled. -#' (Default: \code{TRUE}) -#' -#' @param parse.labels \code{Logical scalar}. Should labels be parsed. +#' \item \code{repl.underscore}: \code{Character scalar}. Used to replace +#' underscores in the labels. (Default: \code{" "}) +#' +#' \item \code{vec.text}: \code{Logical scalar}. Should text instead of labels +#' be used to label vectors. (Default: \code{TRUE}) +#' +#' \item \code{repel.labels}: \code{Logical scalar}. Should labels be +#' repelled. (Default: \code{TRUE}) +#' +#' \item \code{parse.labels}: \code{Logical scalar}. Should labels be parsed. #' (Default: \code{TRUE}) -#' -#' @param add.significance \code{Logical scalar}. Should explained variance and p-value -#' appear in the labels. (Default: \code{TRUE}) -#' -#' @param add.expl.var \code{Logical scalar}. Should explained variance appear on the -#' coordinate axes. (Default: \code{TRUE}) #' -#' @param ... additional parameters for plotting, inherited from -#' \code{\link[scater:plotReducedDim]{plotReducedDim}}, -#' \code{\link[ggplot2:geom_label]{geom_label}} and -#' \code{\link[ggrepel:geom_label_repel]{geom_label_repel}}. +#' \item \code{add.significance}: \code{Logical scalar}. Should explained +#' variance and p-value appear in the labels. (Default: \code{TRUE}) +#' +#' \item \code{add.expl.var}: \code{Logical scalar}. Should explained +#' variance appear on the coordinate axes. (Default: \code{TRUE}) +#' } +#' #' #' @details #' \code{plotRDA} and \code{plotCCA} create an RDA/CCA plot starting from the @@ -104,42 +105,37 @@ #' tse <- enterotype #' #' # Run RDA and store results into TreeSE -#' tse <- addRDA(tse, -#' formula = assay ~ ClinicalStatus + Gender + Age, -#' FUN = vegan::vegdist, -#' distance = "bray", -#' na.action = na.exclude) +#' tse <- addRDA( +#' tse, +#' formula = assay ~ ClinicalStatus + Gender + Age, +#' FUN = getDissimilarity, +#' distance = "bray", +#' na.action = na.exclude +#' ) #' #' # Create RDA plot coloured by variable -#' plotRDA(tse, "RDA", -#' colour.by = "ClinicalStatus") +#' plotRDA(tse, "RDA", colour.by = "ClinicalStatus") #' #' # Create RDA plot with empty ellipses -#' plotRDA(tse, "RDA", -#' colour.by = "ClinicalStatus", -#' add.ellipse = "colour") +#' plotRDA(tse, "RDA", colour.by = "ClinicalStatus", add.ellipse = "colour") #' #' # Create RDA plot with text encased in labels -#' plotRDA(tse, "RDA", -#' colour.by = "ClinicalStatus", -#' vec.text = FALSE) +#' plotRDA(tse, "RDA", colour.by = "ClinicalStatus", vec.text = FALSE) #' #' # Create RDA plot without repelling text -#' plotRDA(tse, "RDA", -#' colour.by = "ClinicalStatus", -#' repel.labels = FALSE) +#' plotRDA(tse, "RDA", colour.by = "ClinicalStatus", repel.labels = FALSE) #' #' # Create RDA plot without vectors -#' plotRDA(tse, "RDA", -#' colour.by = "ClinicalStatus", -#' add.vectors = FALSE) +#' plotRDA(tse, "RDA", colour.by = "ClinicalStatus", add.vectors = FALSE) #' #' # Calculate RDA as a separate object -#' rda_mat <- getRDA(tse, -#' formula = assay ~ ClinicalStatus + Gender + Age, -#' FUN = vegan::vegdist, -#' distance = "bray", -#' na.action = na.exclude) +#' rda_mat <- getRDA( +#' tse, +#' formula = assay ~ ClinicalStatus + Gender + Age, +#' FUN = getDissimilarity, +#' distance = "bray", +#' na.action = na.exclude +#' ) #' #' # Create RDA plot from RDA matrix #' plotRDA(rda_mat) @@ -149,7 +145,7 @@ NULL #' @aliases plotRDA #' @export setGeneric("plotCCA", signature = c("x"), - function(x, ...) standardGeneric("plotCCA")) + function(x, ...) standardGeneric("plotCCA")) #' @rdname plotCCA #' @aliases plotRDA @@ -181,93 +177,17 @@ setGeneric("plotRDA", signature = c("x"), #' @aliases plotCCA #' @export setMethod("plotRDA", signature = c(x = "SingleCellExperiment"), - function(x, dimred, - add.ellipse = TRUE, ellipse.alpha = 0.2, ellipse.linewidth = 0.1, ellipse.linetype = 1, - confidence.level = 0.95, vec.size = 0.5, vec.color = vec.colour, vec.colour = "black", vec.linetype = 1, - arrow.size = 0.25, label.color = label.colour, label.colour = "black", label.size = 4, - vec.text = TRUE, repel.labels = TRUE, sep.group = "\U2014", repl.underscore = " ", - add.significance = TRUE, add.expl.var = TRUE, add.vectors = TRUE, parse.labels = TRUE, ...){ + function(x, dimred, ...){ ###################### Input check ######################## - if( !(add.ellipse %in% c(TRUE, FALSE, "fill", "color", "colour")) ){ - stop("'add.ellipse' must be one of c(TRUE, FALSE, 'fill', 'color', 'colour').", call. = FALSE) - } - if ( !.is_a_bool(add.vectors) ){ - stop("'add.vectors must be TRUE or FALSE.", call. = FALSE) - } - if ( !add.vectors ){ - warning("'add.vectors' is FALSE, so other arguments for vectors and labels will be disregarded.", call. = FALSE) - } - if( !.is_a_bool(vec.text) ){ - stop("'vec.text' must be TRUE or FALSE.", call. = FALSE) - } - if( !.is_a_bool(repel.labels) ){ - stop("'repel.labels' must be TRUE or FALSE.", call. = FALSE) - } - if( !.is_a_bool(parse.labels) ){ - stop("'parse.labels' must be TRUE or FALSE.", call. = FALSE) - } - if( !.is_a_bool(add.significance) ){ - stop("'add.significance' must be TRUE or FALSE.", call. = FALSE) - } - if( parse.labels && !add.significance ){ - parse.labels <- FALSE - warning("'parse.labels' was turned off because 'add.significance' is FALSE.", call. = FALSE) - } - if( !.is_a_bool(add.expl.var) ){ - stop("'add.expl.var' must be TRUE or FALSE.", call. = FALSE) - } - if( !.are_whole_numbers(ellipse.linetype) ){ - stop("'ellipse.linetype' must be a whole number.", call. = FALSE) - } - if( !.are_whole_numbers(ellipse.linetype) ){ - stop("'vec.linetype' must be a whole number.", call. = FALSE) - } - if ( !(is.numeric(ellipse.alpha) && ellipse.alpha > 0 && ellipse.alpha < 1 ) ) { - stop("'ellipse.alpha' must be a number between 0 and 1.", call. = FALSE) - } - if ( !(is.numeric(ellipse.linewidth) && ellipse.linewidth > 0) ) { - stop("'ellipse.linewidth' must be a positive number.", call. = FALSE) - } - if( !(is.numeric(confidence.level) && confidence.level > 0 && confidence.level < 1) ) { - stop("'confidence.level' must be a number between 0 and 1.", call. = FALSE) - } - if ( !(is.numeric(vec.size) && vec.size > 0) ) { - stop("'vec.size' must be a positive number.", call. = FALSE) - } - if ( !(is.numeric(arrow.size) && arrow.size > 0) ) { - stop("'arrow.size' must be a positive number.", call. = FALSE) - } - if ( !(is.numeric(label.size) && label.size > 0) ) { - stop("'label.size' must be a positive number.", call. = FALSE) - } - if ( !.is_non_empty_string(vec.color) ) { - stop("'vec.color' must be a non-empty string specifying a colour", call. = FALSE) - } - if ( !.is_non_empty_string(label.color) ) { - stop("'label.color' must be a non-empty string specifying a colour", call. = FALSE) - } - if ( !.is_a_string(sep.group) ) { - stop("'sep.group' must be a string specifying a separator.", call. = FALSE) - } - if ( !.is_a_string(repl.underscore) ) { - stop("'repl.underscore' must be a string.", call. = FALSE) + # Check dimred + if( !dimred %in% reducedDimNames(x) ){ + stop("'dimred' must specify reducedDim.", call. = FALSE) } ###################### Input check end #################### # Get data for plotting - plot_data <- .incorporate_rda_vis( - x, dimred, sep.group = sep.group, repl.underscore = repl.underscore, - add.significance = add.significance, add.expl.var = add.expl.var, - add.ellipse = add.ellipse, add.vectors = add.vectors, ... - ) + plot_data <- .incorporate_rda_vis(x, dimred, ...) # Create a plot - plot <- .rda_plotter( - plot_data, ellipse.alpha = ellipse.alpha, ellipse.linewidth = ellipse.linewidth, - ellipse.linetype = ellipse.linetype, confidence.level = confidence.level, vec.size = vec.size, - vec.color = vec.color, vec.colour = vec.colour, vec.linetype = vec.linetype, - arrow.size = arrow.size, label.color = label.color, label.colour = label.colour, - label.size = label.size, vec.text = vec.text, add.ellipse = add.ellipse, - repel.labels = repel.labels, parse.labels = parse.labels, ... - ) + plot <- .rda_plotter(plot_data, ...) return(plot) } ) @@ -291,8 +211,9 @@ setMethod("plotRDA", signature = c(x = "matrix"), .rda2tse <- function(object) { # Convert rda/cca object to TreeSE object <- TreeSummarizedExperiment( - assays = matrix(ncol = nrow(object), dimnames = list(NULL, rownames(object))), - reducedDims = list(RDA = object) + assays = matrix( + ncol = nrow(object), dimnames = list(NULL, rownames(object))), + reducedDims = list(RDA = object) ) return(object) } @@ -307,17 +228,39 @@ setMethod("plotRDA", signature = c(x = "matrix"), add.significance = TRUE, add.expl.var = TRUE, add.ellipse = TRUE, add.vectors = TRUE, vec.lab = NULL, expl.var = expl_var, expl_var = NULL, - sep.group = "\U2012", repl.underscore = " ", ...){ - - # Check dimred - if( !dimred %in% reducedDimNames(tse) ){ - stop("'dimred' must specify reducedDim.", call. = FALSE) + sep.group = "\U2014", repl.underscore = " ", ...){ + ###################### Input check ######################## + if( !(add.ellipse %in% c(TRUE, FALSE, "fill", "color", "colour")) ){ + stop("'add.ellipse' must be one of c(TRUE, FALSE, 'fill', ", + "'color').", call. = FALSE) + } + if( !.is_a_bool(add.vectors) ){ + stop("'add.vectors must be TRUE or FALSE.", call. = FALSE) + } + if( !add.vectors ){ + warning("'add.vectors' is FALSE, so other arguments for vectors ", + "and labels will be disregarded.", call. = FALSE) + } + if( !.is_a_bool(add.significance) ){ + stop("'add.significance' must be TRUE or FALSE.", call. = FALSE) } + if( !.is_a_bool(add.expl.var) ){ + stop("'add.expl.var' must be TRUE or FALSE.", call. = FALSE) + } + if ( !.is_a_string(sep.group) ) { + stop("'sep.group' must be a string specifying a separator.", + call. = FALSE) + } + if ( !.is_a_string(repl.underscore) ) { + stop("'repl.underscore' must be a string.", call. = FALSE) + } + ###################### Input check end #################### # Get reducedDim reduced_dim <- reducedDim(tse, dimred) # Check that there are at least 2 coordinates if( ncol(reduced_dim) < 2 ){ - stop("reducedDim specified by 'dimred' must have at least 2 columns.", call. = FALSE) + stop("reducedDim specified by 'dimred' must have at least 2 columns.", + call. = FALSE) } # Only 2 dimensions are supported currently ncomponents <- 2 @@ -335,11 +278,12 @@ setMethod("plotRDA", signature = c(x = "matrix"), # If it cannot be found, give warning warning( paste("RDA/CCA object was not found. Please compute", - "RDA/CCA by using addCCA or getCCA."), call. = FALSE) + "RDA/CCA by using addCCA or getCCA."), call. = FALSE) } } - # Get scatter plot with plotReducedDim --> keep theme similar between ordination methods + # Get scatter plot with plotReducedDim --> keep theme similar between + # ordination methods plot <- plotReducedDim( tse, dimred = dimred, ncomponents = ncomponents, colour_by = colour_by, percentVar = expl_var, ...) @@ -404,8 +348,8 @@ setMethod("plotRDA", signature = c(x = "matrix"), } else{ # Check that user-provided labels are correct length if( length(vec.lab) != nrow(vector_data) ){ - stop("Number of labels in 'vec_lab' do not match with number of vectors.", - call. = FALSE) + stop("Number of labels in 'vec_lab' do not match with number ", + "of vectors.", call. = FALSE) } # If they are, add labels to data vector_data$vector_label <- vec.lab @@ -450,7 +394,7 @@ setMethod("plotRDA", signature = c(x = "matrix"), # Make vector labels more tidy, i.e, separate variable and group names. # Replace also underscores with space .tidy_vector_labels <- function( - vector_label, coldata, sep.group = "\U2014", repl.underscore = " ", ...){ + vector_label, coldata, sep.group, repl.underscore, ...){ # Get variable names from sample metadata var_names <- colnames(coldata) # Loop through vector labels @@ -460,8 +404,9 @@ setMethod("plotRDA", signature = c(x = "matrix"), # If the vector label includes also group name if( !name %in% var_names ){ # Get the group name - group_name <- unique( coldata[[var_name]] )[ - which( paste0(var_name, unique( coldata[[var_name]] )) == name ) ] + group_name <- unique( coldata[[var_name]] )[ + which( + paste0(var_name, unique( coldata[[var_name]] )) == name ) ] # Modify vector so that group is separated from variable name new_name <- paste0(var_name, " ", sep.group, " ", group_name) } else{ @@ -478,37 +423,96 @@ setMethod("plotRDA", signature = c(x = "matrix"), .add_signif_to_vector_labels <- function( vector_label, var_names, signif_data, repl.underscore = " ", ...){ # Replace underscores from significance data and variable names to match labels - rownames(signif_data) <- sapply(rownames(signif_data), function(x) gsub("_", repl.underscore, x)) - var_names <- sapply(var_names, function(x) gsub("_", repl.underscore, x)) + rownames(signif_data) <- vapply( + rownames(signif_data), function(x) gsub("_", repl.underscore, x), + character(1L)) + var_names <- vapply( + var_names, function(x) gsub("_", repl.underscore, x), character(1L)) # Loop through vector labels - vector_label <- sapply(vector_label, FUN = function(name){ + vector_label <- vapply(vector_label, FUN = function(name){ # Get the real variable name from sample metadata var_name <- var_names[ sapply(var_names, function(x) grepl(x, name)) ] # Add percentage how much this variable explains, and p-value - new_name <- expr( - paste(!!name, " (", - !!format( - round( signif_data[var_name, "Explained variance"]*100, 1), - nsmall = 1), "%, ", italic("P"), " = ", - !!gsub("0\\.","\\.", format( - round( signif_data[var_name, "Pr(>F)"], 3), - nsmall = 3)), ")")) + new_name <- expr(paste(!!name, " (", + !!format(round(signif_data[var_name, "Explained variance"]*100, 1), + nsmall = 1), "%, ", italic("P"), " = ", + !!gsub("0\\.","\\.", format(round( signif_data[var_name, "Pr(>F)"], + 3), nsmall = 3)), ")")) return(new_name) - }) + }, character(1L)) return(vector_label) } # Plot based on the data #' @importFrom ggrepel geom_text_repel geom_label_repel .rda_plotter <- function( - plot_data, ellipse.alpha = 0.2, ellipse.linewidth = 0.1, ellipse.linetype = 1, confidence.level = 0.95, + plot_data, ellipse.alpha = 0.2, ellipse.linewidth = 0.1, + ellipse.linetype = 1, confidence.level = 0.95, vec.size = 0.5, vec.color = vec.colour, vec.colour = "black", vec.linetype = 1, arrow.size = 0.25, min.segment.length = 5, label.color = label.colour, label.colour = "black", label.size = 4, - parse.labels = TRUE, vec.text = TRUE, repel.labels = TRUE, add.ellipse = TRUE, + add.significance = TRUE, parse.labels = TRUE, vec.text = TRUE, + repel.labels = TRUE, add.ellipse = TRUE, position = NULL, nudge_x = NULL, nudge_y = NULL, direction = "both", max.overlaps = 10, check_overlap = FALSE, ...){ + ###################### Input check ######################## + if( !(add.ellipse %in% c(TRUE, FALSE, "fill", "color", "colour")) ){ + stop("'add.ellipse' must be one of c(TRUE, FALSE, 'fill', ", + "'color', 'colour').", call. = FALSE) + } + if( !.is_a_bool(vec.text) ){ + stop("'vec.text' must be TRUE or FALSE.", call. = FALSE) + } + if( !.is_a_bool(repel.labels) ){ + stop("'repel.labels' must be TRUE or FALSE.", call. = FALSE) + } + if( !.is_a_bool(parse.labels) ){ + stop("'parse.labels' must be TRUE or FALSE.", call. = FALSE) + } + if( !.is_a_bool(add.significance) ){ + stop("'add.significance' must be TRUE or FALSE.", call. = FALSE) + } + if( parse.labels && !add.significance ){ + parse.labels <- FALSE + warning("'parse.labels' was turned off because 'add.significance' ", + "is FALSE.", call. = FALSE) + } + if( !.are_whole_numbers(ellipse.linetype) ){ + stop("'vec.linetype' must be a whole number.", call. = FALSE) + } + if ( !(is.numeric(ellipse.alpha) && ellipse.alpha > 0 && + ellipse.alpha < 1 ) ) { + stop("'ellipse.alpha' must be a number between 0 and 1.", + call. = FALSE) + } + if ( !(is.numeric(ellipse.linewidth) && ellipse.linewidth > 0) ) { + stop("'ellipse.linewidth' must be a positive number.", + call. = FALSE) + } + if( !(is.numeric(confidence.level) && confidence.level > 0 && + confidence.level < 1) ) { + stop("'confidence.level' must be a number between 0 and 1.", + call. = FALSE) + } + if ( !(is.numeric(vec.size) && vec.size > 0) ) { + stop("'vec.size' must be a positive number.", call. = FALSE) + } + if ( !(is.numeric(arrow.size) && arrow.size > 0) ) { + stop("'arrow.size' must be a positive number.", call. = FALSE) + } + if ( !(is.numeric(label.size) && label.size > 0) ) { + stop("'label.size' must be a positive number.", call. = FALSE) + } + if ( !.is_non_empty_string(vec.color) ) { + stop("'vec.color' must be a non-empty string specifying a colour", + call. = FALSE) + } + if ( !.is_non_empty_string(label.color) ) { + stop("'label.color' must be a non-empty string specifying a colour", + call. = FALSE) + } + ###################### Input check end #################### # Get the scatter plot plot <- plot_data[["plot"]] # Add ellipse @@ -520,19 +524,22 @@ setMethod("plotRDA", signature = c(x = "matrix"), colour_var <- attributes(plot_data$ellipse_data)$colour_by # Add ellipses to plot (fill or colour the edge) if( add.ellipse %in% c(TRUE, "fill") ){ - plot <- plot + - stat_ellipse(data = data, - aes(x = .data[[xvar]], y = .data[[yvar]], - color = .data[[colour_var]], fill = after_scale(color)), - geom = "polygon", alpha = ellipse.alpha, - linewidth = ellipse.linewidth, linetype = ellipse.linetype, level = confidence.level) + plot <- plot + stat_ellipse( + data = data, aes( + x = .data[[xvar]], y = .data[[yvar]], + color = .data[[colour_var]], fill = after_scale(color)), + geom = "polygon", alpha = ellipse.alpha, + linewidth = ellipse.linewidth, linetype = ellipse.linetype, + level = confidence.level) } else if ( add.ellipse %in% c("color", "colour") ){ plot <- plot + - stat_ellipse(data = data, - aes(x = .data[[xvar]], y = .data[[yvar]], color = .data[[colour_var]]), - geom = "polygon", alpha = 0, linetype = ellipse.linetype, level = confidence.level) + stat_ellipse( + data = data, aes( + x = .data[[xvar]], y = .data[[yvar]], + color = .data[[colour_var]]), + geom = "polygon", alpha = 0, linetype = ellipse.linetype, + level = confidence.level) } - } # Add vectors if( !is.null(plot_data$vector_data) ){ @@ -542,49 +549,51 @@ setMethod("plotRDA", signature = c(x = "matrix"), yvar <- colnames(data)[[2]] # Add vectors plot <- plot + - geom_segment(data = data, - aes(x = 0, y = 0, xend = .data[[xvar]], yend = .data[[yvar]], - group = .data[["group"]]), - arrow = arrow(length = unit(arrow.size, "cm")), - color = vec.color, linetype = vec.linetype, size = vec.size) + geom_segment( + data = data, + aes( + x = 0, y = 0, xend = .data[[xvar]], yend = .data[[yvar]], + group = .data[["group"]]), + arrow = arrow(length = unit(arrow.size, "cm")), + color = vec.color, linetype = vec.linetype, size = vec.size) # Add vector labels (text or label) # Make list of arguments for geom_text/geom_label label_args <- list( - data = data, - mapping = aes(x = .data[[xvar]], y = .data[[yvar]]), - label = data[["vector_label"]], parse = parse.labels, - color = label.color, size = label.size, stat = "identity", - nudge_x = nudge_x, nudge_y = nudge_y, show.legend = NA, - na.rm = FALSE, inherit.aes = TRUE - ) + data = data, + mapping = aes(x = .data[[xvar]], y = .data[[yvar]]), + label = data[["vector_label"]], parse = parse.labels, + color = label.color, size = label.size, stat = "identity", + nudge_x = nudge_x, nudge_y = nudge_y, show.legend = NA, + na.rm = FALSE, inherit.aes = TRUE + ) # Repel text if( repel.labels ){ - # Add arguments for geom_text_repel/geom_label_repel to list - label_args <- c( - label_args, min.segment.length = min.segment.length, - box.padding = 0.25, point.padding = 1e-06, force = 1, force_pull = 1, - max.time = 0.5, max.iter = 10000, max.overlaps = max.overlaps, - direction = direction, seed = NA, verbose = FALSE - ) - # repelled text - if( vec.text ){ - plot <- plot + do.call("geom_text_repel", label_args) - # repelled labels - } else{ - plot <- plot + do.call("geom_label_repel", label_args) - } + # Add arguments for geom_text_repel/geom_label_repel to list + label_args <- c( + label_args, min.segment.length = min.segment.length, + box.padding = 0.25, point.padding = 1e-06, force = 1, + force_pull = 1, + max.time = 0.5, max.iter = 10000, max.overlaps = max.overlaps, + direction = direction, seed = NA, verbose = FALSE + ) + # repelled text + if( vec.text ){ + plot <- plot + do.call("geom_text_repel", label_args) + # repelled labels + } else{ + plot <- plot + do.call("geom_label_repel", label_args) + } # Do not repel text } else{ - # not repelled text - if( vec.text ){ - label_args <- c(label_args, check_overlap = check_overlap) - plot <- plot + do.call("geom_text", label_args) - # not repelled labels - } else{ - plot <- plot + do.call("geom_label", label_args) - } + # not repelled text + if( vec.text ){ + label_args <- c(label_args, check_overlap = check_overlap) + plot <- plot + do.call("geom_text", label_args) + # not repelled labels + } else{ + plot <- plot + do.call("geom_label", label_args) + } } - } return(plot) } diff --git a/R/plotLoadings.R b/R/plotLoadings.R index 7a9254d5..3222d520 100644 --- a/R/plotLoadings.R +++ b/R/plotLoadings.R @@ -25,7 +25,7 @@ #' (Default: \code{NULL}) #' #' @param ... additional parameters for plotting. -#' \itemize{ +#' \itemize{ #' \item \code{n}: \code{Integer scalar}. Number of features to be plotted. #' Applicable when \code{layout="barplot"}. (Default: \code{10})) #' diff --git a/man/plotCCA.Rd b/man/plotCCA.Rd index 959a809d..61929e03 100644 --- a/man/plotCCA.Rd +++ b/man/plotCCA.Rd @@ -17,110 +17,85 @@ plotCCA(x, ...) plotRDA(x, ...) -\S4method{plotRDA}{SingleCellExperiment}( - x, - dimred, - add.ellipse = TRUE, - ellipse.alpha = 0.2, - ellipse.linewidth = 0.1, - ellipse.linetype = 1, - confidence.level = 0.95, - vec.size = 0.5, - vec.color = vec.colour, - vec.colour = "black", - vec.linetype = 1, - arrow.size = 0.25, - label.color = label.colour, - label.colour = "black", - label.size = 4, - vec.text = TRUE, - repel.labels = TRUE, - sep.group = "—", - repl.underscore = " ", - add.significance = TRUE, - add.expl.var = TRUE, - add.vectors = TRUE, - parse.labels = TRUE, - ... -) +\S4method{plotRDA}{SingleCellExperiment}(x, dimred, ...) \S4method{plotRDA}{matrix}(x, ...) } \arguments{ \item{x}{a \code{\link[TreeSummarizedExperiment:TreeSummarizedExperiment-constructor]{TreeSummarizedExperiment}} -or a matrix of weights. The latter is returned as output from \code{\link[mia:runCCA]{getRDA}}.} +or a matrix of weights. The latter is returned as output from +\code{\link[mia:runCCA]{getRDA}}.} \item{...}{additional parameters for plotting, inherited from \code{\link[scater:plotReducedDim]{plotReducedDim}}, \code{\link[ggplot2:geom_label]{geom_label}} and -\code{\link[ggrepel:geom_label_repel]{geom_label_repel}}.} +\code{\link[ggrepel:geom_label_repel]{geom_label_repel}}. +\itemize{ +\item \code{add.ellipse}: One of +\code{c(TRUE, FALSE, "fill", "colour")}, indicating whether +ellipses should be present, absent, filled or colored. +(default: \code{ellipse.fill = TRUE}) -\item{dimred}{\code{Character scalar} or \code{integer scalar}. Determines the reduced dimension to -plot. This is the output of \code{\link[mia:runCCA]{addRDA}} and resides in -\code{reducedDim(tse, dimred)}.} - -\item{add.ellipse}{One of \code{c(TRUE, FALSE, "fill", "colour", "color")}, -indicating whether ellipses should be present, absent, filled or colored. -(default: \code{ellipse.fill = TRUE})} - -\item{ellipse.alpha}{\code{Numeric scalar}. Between 0 and 1. Adjusts the opacity of ellipses. -(Default: \code{0.2})} +\item \code{ellipse.alpha}: \code{Numeric scalar}. Between 0 and 1. +Adjusts the opacity of ellipses. (Default: \code{0.2}) -\item{ellipse.linewidth}{\code{Numeric scalar}. Specifies the size of ellipses. -(Default: \code{0.1})} +\item \code{ellipse.linewidth}: \code{Numeric scalar}. Specifies the size +of ellipses. (Default: \code{0.1}) -\item{ellipse.linetype}{\code{Integer scalar}. Specifies the style of ellipses. -(Default: \code{1})} +\item \code{ellipse.linetype}: \code{Integer scalar}. Specifies the style +of ellipses. (Default: \code{1}) -\item{confidence.level}{\code{Numeric scalar}. Between 0 and 1. Adjusts confidence level. -(Default: \code{0.95})} +\item \code{confidence.level}: \code{Numeric scalar}. Between 0 and 1. +Adjusts confidence level. (Default: \code{0.95}) -\item{vec.size}{\code{Numeric scalar}. Specifies the size of vectors. -(Default: \code{0.5})} +\item \code{add.vectors}: \code{Logical scalar}. Should vectors appear in +the plot. (Default: \code{TRUE}) -\item{vec.color}{Alias for \code{vec.colour}.} +\item \code{vec.size}: \code{Numeric scalar}. Specifies the size of +vectors. (Default: \code{0.5}) -\item{vec.colour}{\code{Character scalar}. Specifies the colour of vectors. -(Default: \code{"black"})} +\item \code{vec.colour}: \code{Character scalar}. Specifies the colour of +vectors. (Default: \code{"black"}) -\item{vec.linetype}{\code{Integer scalar}. Specifies the style of vector lines. -(Default: \code{1})} +\item \code{vec.linetype}: \code{Integer scalar}. Specifies the style of +vector lines. (Default: \code{1}) -\item{arrow.size}{\code{Numeric scalar}. Specifies the size of arrows. -(defaults: \code{arrow.size = 0.25})} +\item \code{arrow.size}: \code{Numeric scalar}. Specifies the size of +arrows. (Default: \code{arrow.size = 0.25}) -\item{label.color}{Alias for \code{label.colour}.} +\item \code{label.size}: \code{Numeric scalar}. Specifies the size of text +and labels. (Default: \code{4}) -\item{label.colour}{\code{Character scalar}. Specifies the colour of text and labels. -(Default: \code{"black"})} +\item \code{label.colour}: \code{Character scalar}. Specifies the colour of +text and labels. (Default: \code{"black"}) -\item{label.size}{\code{Numeric scalar}. Specifies the size of text and labels. -(Default: \code{4})} +\item \code{sep.group}: \code{Character scalar}. Specifies the separator +used in the labels. (Default: \code{"\U2014"}) -\item{vec.text}{\code{Logical scalar}. Should text instead of labels be used to label vectors. -(Default: \code{TRUE})} +\item \code{repl.underscore}: \code{Character scalar}. Used to replace +underscores in the labels. (Default: \code{" "}) -\item{repel.labels}{\code{Logical scalar}. Should labels be repelled. -(Default: \code{TRUE})} +\item \code{vec.text}: \code{Logical scalar}. Should text instead of labels +be used to label vectors. (Default: \code{TRUE}) -\item{sep.group}{\code{Character scalar}. Specifies the separator used in the labels. -(Default: \code{"\U2014"})} +\item \code{repel.labels}: \code{Logical scalar}. Should labels be +repelled. (Default: \code{TRUE}) -\item{repl.underscore}{\code{Character scalar}. Used to replace underscores in the labels. -(Default: \code{" "})} +\item \code{parse.labels}: \code{Logical scalar}. Should labels be parsed. +(Default: \code{TRUE}) -\item{add.significance}{\code{Logical scalar}. Should explained variance and p-value -appear in the labels. (Default: \code{TRUE})} +\item \code{add.significance}: \code{Logical scalar}. Should explained +variance and p-value appear in the labels. (Default: \code{TRUE}) -\item{add.expl.var}{\code{Logical scalar}. Should explained variance appear on the -coordinate axes. (Default: \code{TRUE})} +\item \code{add.expl.var}: \code{Logical scalar}. Should explained +variance appear on the coordinate axes. (Default: \code{TRUE}) +}} -\item{add.vectors}{\code{Logical scalar}. Should vectors appear in the plot. -(Default: \code{TRUE})} - -\item{parse.labels}{\code{Logical scalar}. Should labels be parsed. -(Default: \code{TRUE})} +\item{dimred}{\code{Character scalar} or \code{integer scalar}. Determines +the reduced dimension to +plot. This is the output of \code{\link[mia:runCCA]{addRDA}} and resides in +\code{reducedDim(tse, dimred)}.} } \value{ A \code{ggplot2} object @@ -150,42 +125,37 @@ data("enterotype", package = "mia") tse <- enterotype # Run RDA and store results into TreeSE -tse <- addRDA(tse, - formula = assay ~ ClinicalStatus + Gender + Age, - FUN = vegan::vegdist, - distance = "bray", - na.action = na.exclude) +tse <- addRDA( + tse, + formula = assay ~ ClinicalStatus + Gender + Age, + FUN = getDissimilarity, + distance = "bray", + na.action = na.exclude + ) # Create RDA plot coloured by variable -plotRDA(tse, "RDA", - colour.by = "ClinicalStatus") +plotRDA(tse, "RDA", colour.by = "ClinicalStatus") # Create RDA plot with empty ellipses -plotRDA(tse, "RDA", - colour.by = "ClinicalStatus", - add.ellipse = "colour") +plotRDA(tse, "RDA", colour.by = "ClinicalStatus", add.ellipse = "colour") # Create RDA plot with text encased in labels -plotRDA(tse, "RDA", - colour.by = "ClinicalStatus", - vec.text = FALSE) +plotRDA(tse, "RDA", colour.by = "ClinicalStatus", vec.text = FALSE) # Create RDA plot without repelling text -plotRDA(tse, "RDA", - colour.by = "ClinicalStatus", - repel.labels = FALSE) +plotRDA(tse, "RDA", colour.by = "ClinicalStatus", repel.labels = FALSE) # Create RDA plot without vectors -plotRDA(tse, "RDA", - colour.by = "ClinicalStatus", - add.vectors = FALSE) +plotRDA(tse, "RDA", colour.by = "ClinicalStatus", add.vectors = FALSE) # Calculate RDA as a separate object -rda_mat <- getRDA(tse, - formula = assay ~ ClinicalStatus + Gender + Age, - FUN = vegan::vegdist, - distance = "bray", - na.action = na.exclude) +rda_mat <- getRDA( + tse, + formula = assay ~ ClinicalStatus + Gender + Age, + FUN = getDissimilarity, + distance = "bray", + na.action = na.exclude + ) # Create RDA plot from RDA matrix plotRDA(rda_mat)