1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
#' Compute log-normalized expression values
#'
#' Compute log-transformed normalized expression values from a count matrix in a \linkS4class{SingleCellExperiment} object.
#'
#' @param x A \linkS4class{SingleCellExperiment} or \linkS4class{SummarizedExperiment} object containing a count matrix.
#' @inheritParams normalizeCounts
#' @param use.altexps,use_altexps Deprecated, use \code{\link{applySCE}} instead (see Examples).
#' @param ... For the generic, additional arguments passed to specific methods.
#'
#' For the methods, additional arguments passed to \code{\link{normalizeCounts}}.
#' @param name String containing an assay name for storing the output normalized values.
#' Defaults to \code{"logcounts"} when \code{transform="log"}, \code{"ashcounts"} when \code{transform="asinh"}, and \code{"normcounts"} otherwise.
#' @param BPPARAM A \linkS4class{BiocParallelParam} object specifying how library size factor calculations should be parallelized.
#' Only used if \code{size.factors} is not specified.
#' @param size_factors,pseudo_count,center_size_factors,exprs_values Deprecated.
#'
#' @details
#' This function is a convenience wrapper around \code{\link{normalizeCounts}}.
#' It returns a \linkS4class{SingleCellExperiment} or \linkS4class{SummarizedExperiment} containing the normalized values in a separate assay.
#' This makes it easier to perform normalization by avoiding book-keeping errors during a long analysis workflow.
#'
#' If \code{NULL}, size factors are determined as described in \code{\link{normalizeCounts}}.
#' \code{subset.row} and \code{normalize.all} have the same interpretation as for \code{\link{normalizeCounts}}.
#'
#' If \code{x} is a SingleCellExperiment, normalization is not applied to any alternative Experiments.
#' Users can call \code{\link{applySCE}} to perform the normalization on each alternative Experiment - see Examples.
#' Any Experiment-specific size factors will be automatically used, otherwise library size-based factors will be derived from the column sums.
#'
#' @return
#' \code{x} is returned containing the (log-)normalized expression values in an additional assay named as \code{name}.
#'
#' If \code{x} is a \linkS4class{SingleCellExperiment}, the size factors used for normalization are stored in \code{\link{sizeFactors}}.
#' These are centered if \code{center.size.factors=TRUE}.
#'
#' @author Aaron Lun, based on code by Davis McCarthy
#' @seealso
#' \code{\link{normalizeCounts}}, which is used to compute the normalized expression values.
#'
#' @examples
#' example_sce <- mockSCE()
#'
#' # Standard library size normalization:
#' example_sce2 <- logNormCounts(example_sce)
#' assayNames(example_sce2)
#' logcounts(example_sce2)[1:5,1:5]
#'
#' # Without logging, the assay is 'normcounts':
#' example_sce2 <- logNormCounts(example_sce, log=FALSE)
#' assayNames(example_sce2)
#' normcounts(example_sce2)[1:5,1:5]
#'
#' # Pre-loading with size factors:
#' example_sce2 <- computeMedianFactors(example_sce)
#' example_sce2 <- logNormCounts(example_sce2)
#' logcounts(example_sce2)[1:5,1:5]
#'
#' # Also normalizing the alternative experiments:
#' example_sce2 <- applySCE(example_sce, logNormCounts)
#' logcounts(altExp(example_sce2))[1:5,1:5]
#'
#' @name logNormCounts
NULL
#' @export
#' @rdname logNormCounts
setGeneric("logNormCounts", function(x, ...) standardGeneric("logNormCounts"))
#' @export
#' @rdname logNormCounts
#' @importClassesFrom SummarizedExperiment SummarizedExperiment
setMethod("logNormCounts", "SummarizedExperiment", function(x, size.factors=NULL,
log=NULL, transform=c("log", "none", "asinh"), pseudo.count=1,
center.size.factors=TRUE, ..., subset.row=NULL, normalize.all=FALSE,
assay.type="counts", name=NULL, BPPARAM=SerialParam(),
size_factors=NULL, pseudo_count=NULL, center_size_factors=NULL, exprs_values=NULL)
{
size.factors <- .replace(size.factors, size_factors)
pseudo.count <- .replace(pseudo.count, pseudo_count)
center.size.factors <- .replace(center.size.factors, center_size_factors)
assay.type <- .replace(assay.type, exprs_values)
transform <- .choose_transform(log, match.arg(transform))
if (!is.null(subset.row) && !normalize.all) {
x <- x[subset.row,,drop=FALSE]
subset.row <- NULL
}
FUN <- .se_lnc(assay.type=assay.type, transform=transform, pseudo.count=pseudo.count, ...,
normalize.all=normalize.all, subset.row=subset.row, name=name, BPPARAM=BPPARAM)
FUN(x, size.factors=size.factors, center.size.factors=center.size.factors)
})
#' @importFrom SummarizedExperiment assay<-
.se_lnc <- function(assay.type, transform, pseudo.count, ..., name) {
args <- list(..., assay.type=assay.type, transform=transform, pseudo.count=pseudo.count)
if (is.null(name)) {
name <- switch(transform,
none="normcounts",
log="logcounts",
asinh="ashcounts"
)
}
function(x, ...) {
out <- do.call(normalizeCounts, c(list(x, ...), args))
assay(x, name) <- out
x
}
}
#' @export
#' @rdname logNormCounts
#' @importFrom BiocGenerics sizeFactors sizeFactors<-
#' @importFrom SingleCellExperiment altExp altExp<- int_metadata int_metadata<-
#' @importClassesFrom SingleCellExperiment SingleCellExperiment
setMethod("logNormCounts", "SingleCellExperiment", function(x, size.factors=sizeFactors(x),
log=NULL, transform=c("log", "none", "asinh"), pseudo.count=1,
center.size.factors=TRUE, ..., subset.row=NULL, normalize.all=FALSE,
assay.type="counts", use.altexps=FALSE, name=NULL, BPPARAM=SerialParam(),
size_factors=NULL, pseudo_count=NULL, center_size_factors=NULL, exprs_values=NULL, use_altexps=NULL)
{
size.factors <- .replace(size.factors, size_factors)
pseudo.count <- .replace(pseudo.count, pseudo_count)
center.size.factors <- .replace(center.size.factors, center_size_factors)
use.altexps <- .replace(use.altexps, use_altexps)
assay.type <- .replace(assay.type, exprs_values)
transform <- .choose_transform(log, match.arg(transform))
if (!is.null(subset.row) && !normalize.all) {
x <- x[subset.row,,drop=FALSE]
subset.row <- NULL
}
# Guarantee that we store (centered) size factors in the output matrix.
if (is.null(size.factors)) {
size.factors <- librarySizeFactors(x, assay.type=assay.type, BPPARAM=BPPARAM, subset.row=subset.row)
}
size.factors <- .center.size.factors(size.factors, center.size.factors)
sizeFactors(x) <- size.factors
# Set center.size.factors=FALSE, as we've already centered above.
FUN <- .se_lnc(assay.type=assay.type, transform=transform, pseudo.count=pseudo.count, ..., name=name)
x <- FUN(x, size.factors=size.factors, center.size.factors=FALSE)
if (transform=="log") {
if (is.null(int_metadata(x)$scater)) {
int_metadata(x)$scater <- list()
}
int_metadata(x)$scater$pseudo.count <- pseudo.count
}
if (!is.null(use.altexps) && !isFALSE(use.altexps)) {
.Deprecated(msg="'use.altexps=' is deprecated.\nUse 'applySCE(x, logNormCounts)' instead.")
}
x
})
|