#' @describeIn TopDownSet Aggregate conditions/runs.
#'
#' Aggregates conditions/runs (columns) in an
#' [TopDownSet-class] object
#' `by` a
#' user-given value (default is the
#' `"Sample"` column of `colData`
#' which has the same value for technical replicates).
#' It combines intensity values and numeric metadata of the grouped
#' conditions/runs (columns) by `mean` and returns a reduced
#' [TopDownSet-class] object.
#'
#' @param x,object `TopDownSet`
#' @param by `list`,
#' grouping variable, in general it refers to technical
#' @param \ldots arguments passed to internal/other methods.
#' replicates (that's why the default is the
#' `"Sample"` column in `colData`).
## @return `TopDownSet`
#' @aliases aggregate,TopDownSet-method
#' @export
setMethod("aggregate", "TopDownSet",
function(x, by=x$Sample, ...) {
d0 <- .logdim(x)
groups <- .groupByLabels(by)
if (length(groups) != ncol(x)) {
stop("'by' has to be of the same length as 'ncol(x)'.")
}
x@assay <- .rowMeansGroup(x@assay, groups)
x@colData <- .aggregateDataFrame(
x@colData, groups, ignoreNumCols=c("Scan", "Condition")
)
d1 <- .logdim(x)
if (validObject(x)) {
.atdsLogMsg(x, "Aggregated ", d0, " to ", d1, ".", addDim=FALSE)
}
})
#' @describeIn TopDownSet Combine `TopDownSet` objects.
#'
#' `combine` allows to combine two or more `TopDownSet` objects.
#' Please note that it uses the default
#' `sampleColumns` to define technical replicates (see [readTopDownFiles()]).and
#' the default `by` argument to group ion injection times for the calculation of
#' the median time (see [updateMedianInjectionTime()]). Both could be modified
#' after `combine` by calling [updateConditionNames()] (with modified
#' `sampleColumns` argument) and [updateMedianInjectionTime()] (with modified
#' `by` argument).
#'
## @param x `TopDownSet`
## @param y `TopDownSet`
## @param \ldots
#' @aliases combine,TopDownSet,TopDownSet-method
#' @export
setMethod("combine",
signature(x="TopDownSet", y="TopDownSet"),
function(x, y) {
x <- callNextMethod()
if (x@tolerance != y@tolerance) {
warning("Matching tolerance differs, choosing the larger one.")
}
x@tolerance <- max(x@tolerance, y@tolerance)
if (any(x@redundantMatching != y@redundantMatching)) {
warning(
"Matching strategies differ, ",
"keeping the strategy of object 'x'."
)
}
if (validObject(x)) {
x
}
})
#' @describeIn TopDownSet Filter by CV.
#'
#' Filtering is done by coefficient of variation across technical replicates
#' (defined by the `by` argument).
#' All fragments below a given `threshold`
#' are removed. The `threshold` is the maximal allowed CV in percent
#' (`sd/mean * 100 < threshold`).
#'
## @param object `TopDownSet`
#' @param threshold `double`, threshold variable.
## @param by `list`, how technical replicates are defined.
## @return `TopDownSet`
#' @aliases filterCv filterCv,TopDownSet-method
#' @export
setMethod("filterCv", "TopDownSet",
function(object, threshold, by=object$Sample, ...) {
if (!is.numeric(threshold) || !length(threshold) == 1L) {
stop("'threshold' has to be a 'numeric' of length one.")
}
if (threshold < 0) {
stop("'threshold' has to be greater than 0.")
}
n0 <- nnzero(object@assay)
group <- .groupByLabels(by)
mm <- .createMaskMatrix(group)
cvs <- tcrossprod(.rowCvsGroup(object@assay, group, na.rm=TRUE), mm)
object@assay[Matrix::which(cvs * 100L > threshold)] <- 0L
object@assay <- drop0(object@assay, is.Csparse=TRUE)
n1 <- nnzero(object@assay)
if (n0 - n1) {
object <- .atdsLogMsg(
object, n0 - n1, " fragments with CV > ", threshold, "% filtered"
)
}
if (validObject(object)) {
object
}
})
#' @describeIn TopDownSet Filter by ion injection time.
#'
#' Filtering is done by maximal allowed deviation and just the technical
#' `keepTopN` replicates with the lowest deviation from the median ion
#' injection time are kept.
#'
## @param object `TopDownSet`
#' @param maxDeviation `double`,
#' maximal allowed deviation in the `log2`
#' injection time in ms in comparison to the median ion injection time.
#' @param keepTopN `integer`, how many technical replicates should be kept?
## @param by `list`, how technical replicates are defined.
## @return `TopDownSet`
#' @aliases filterInjectionTime filterInjectionTime,TopDownSet-method
#' @export
setMethod("filterInjectionTime", "TopDownSet",
function(object, maxDeviation=log2(3), keepTopN=2,
by=object$Sample, ...) {
if (!is.numeric(maxDeviation) || !length(maxDeviation) == 1L) {
stop("'maxDeviation' has to be a 'numeric' of length one.")
}
if (maxDeviation < 0) {
stop("'maxDeviation' has to be greater than 0.")
}
lr <- as.vector(
abs(log2(object$IonInjectionTimeMs / object$MedianIonInjectionTimeMs))
)
i <- intersect(
which(lr <= maxDeviation), .topIdx(-lr, .groupByLabels(by), n=keepTopN)
)
if (length(i) && length(i) != ncol(object)) {
n0 <- ncol(object)
object <- object[, i]
n1 <- ncol(object)
nd <- n0 - n1
object <- .atdsLogMsg(
object, n0 - n1, " scan", if (nd > 1L) { "s" },
" filtered with injection time deviation >= ",
maxDeviation, " or rank >= ", keepTopN + 1L
)
}
if (validObject(object)) {
object
}
})
#' @describeIn TopDownSet Filter by intensity.
#'
#' Filtering is done by removing all fragments that are below a given
#' (absolute/relative) intensity `threshold`.
#
## @param object `TopDownSet`
## @param threshold `double`, remove fragments with intensity below
## `threshold`.
#' @param relative `logical`,
#' if relative is `TRUE` all fragments with
#' intensity below `threshold * max(intensity)`
#' per fragment are removed,
#' otherwise all fragments below `threshold` are removed.
## @return `TopDownSet`
#' @aliases filterIntensity filterIntensity,TopDownSet-method
#' @export
setMethod("filterIntensity", "TopDownSet",
function(object, threshold, relative=TRUE, ...) {
if (!is.numeric(threshold) || !length(threshold) == 1L) {
stop("'threshold' has to be a 'numeric' of length one.")
}
n0 <- nnzero(object@assay)
if (relative) {
if (1L < threshold || threshold < 0L) {
stop("'threshold has to be between 0 and 1.")
}
object@assay <- .drop0rowLt(
object@assay, tol=.rowMax(object@assay) * threshold
)
} else {
object@assay <- drop0(
object@assay,
tol=threshold - 10L * .Machine$double.eps,
is.Csparse=TRUE
)
}
n1 <- nnzero(object@assay)
if (n0 - n1) {
object <- .atdsLogMsg(
object, n0 - n1, " intensity values < ", threshold,
if (relative) { " (relative)" }, " filtered"
)
}
if (validObject(object)) {
object
}
})
#' @describeIn TopDownSet Filter by non-replicated fragments.
#'
#' Filtering is done by removing all fragments that don't replicate across
#' technical replicates.
#'
## @param object `TopDownSet`
#' @param minN `numeric`,
#' if less than `minN` of a fragment are found across
#' technical replicates it is removed.
## @param by `list`, how technical replicates are defined.
## @return `TopDownSet`
#' @aliases filterNonReplicatedFragments
#' filterNonReplicatedFragments,TopDownSet-method
#' @export
setMethod("filterNonReplicatedFragments", "TopDownSet",
function(object, minN=2, by=object$Sample, ...) {
if (!is.numeric(minN) || !length(minN) == 1L) {
stop("'minN' has to be a 'numeric' of length one.")
}
minN <- as.integer(minN)
n0 <- nnzero(object@assay)
object@assay <- .drop0rowReplicates(
object@assay, .groupByLabels(by), minN=minN
)
n1 <- nnzero(object@assay)
if (n0 - n1) {
object <- .atdsLogMsg(
object, n0 - n1, " intensity values of fragments replicated < ",
minN, " times filtered"
)
}
if (validObject(object)) {
object
}
})
#' @describeIn TopDownSet Normalise.
#'
#' Applies *T*otal *I*on *C*urrent normalisation to a
#' [TopDownSet-class] object.
#' The normalisation ist done per scans/conditions (column-wise normalisation).
#'
## @param object `TopDownSet`
#' @param method `character`,
#' normalisation method, currently just `"TIC"`
#' for *T*otal *I*on *C*urrent
#' normalisation of the scans/conditions (column-wise normalisation)
#' is supported.
## @return `TopDownSet`
#' @aliases normalize,TopDownSet-method
#' @export
setMethod("normalize", "TopDownSet",
function(object, method="TIC", ...) {
method <- match.arg(method)
if (method == "TIC") {
object@assay <- .normaliseCols(
object@assay, scale=object$TotIonCurrent
)
.atdsLogMsg(object, "Intensity values normalized to TIC.", addDim=FALSE)
}
})
#' @describeIn TopDownSet Plotting.
#'
#' Plots an [TopDownSet-class] object. The function returns a `list`
#' of `ggplot` objects (one item per condtion).
#' Use `pdf` or another non-interactive device to plot the list of `ggplot`
#' objects (see example section).
#'
## @param x `TopDownSet`
#' @param y `missing`, not used.
#' @param verbose `logical`, verbose output?
#' @examples
#' \dontrun{
#' # plot a single condition
#' # pseudo-code (replace topdownset with your object)
#' plot(topdownset[,1])
#'
#' # plot the whole object
#' pdf("topdown-spectra.pdf", paper="a4r", width=12)
#' # pseudo-code (replace topdownset with your object)
#' plot(topdownset)
#' dev.off()
#' }
setMethod("plot", signature(x="TopDownSet", y="missing"),
function(x, y, ..., verbose=interactive()) {
if (verbose) {
pb <- txtProgressBar(0L, ncol(x), style=3L)
}
l <- vector(mode="list", length=ncol(x))
for (i in seq(along=l)) {
l[[i]] <- .plot(x[, i])
if (verbose) {
setTxtProgressBar(pb, i)
}
}
if (verbose) {
close(pb)
}
l
})
#' @rdname TopDownSet-class
#' @aliases show,TopDownSet-method
#' @export
setMethod("show", "TopDownSet", function(object) {
callNextMethod()
if (length(object@rowViews)) {
cat("- - - Fragment data - - -\n")
cat("Number of theoretical fragments:", length(object@rowViews), "\n")
fragments <- fragmentType(object)
cat0("Theoretical fragment types (", nlevels(fragments), "): ",
paste0(.hft(levels(fragments), n=5), collapse=", "), "\n")
mass <- range(mz(object@rowViews))
cat(sprintf(
"Theoretical mass range: [%.2f;%.2f]\n", mass[1L], mass[2L])
)
}
if (nrow(object@colData)) {
cat("- - - Condition data - - -\n")
cat("Number of conditions:", length(unique(object$Sample)), "\n")
cat("Number of scans:", nrow(object@colData), "\n")
cat0("Condition variables (", ncol(object@colData), "): ",
paste0(.hft(colnames(object@colData), n=2), collapse=", "), "\n")
}
if (all(dim(object))) {
cat("- - - Intensity data - - -\n")
cat(sprintf(
"Size of array: %dx%d (%.2f%% != 0)\n",
nrow(object@assay), ncol(object@assay),
nnzero(object@assay) / length(object@assay) * 100L)
)
if (length(object@assay@x)) {
intensity <- range(object@assay@x)
} else {
intensity <- c(-NA, NA)
}
cat("Number of matched fragments:", nnzero(object@assay), "\n")
cat(sprintf(
"Intensity range: [%.2f;%.2f]\n", intensity[1L], intensity[2L])
)
}
if (length(object@processing)) {
cat("- - - Processing information - - -\n")
cat(paste0(object@processing, collapse="\n"), "\n")
}
invisible(NULL)
})
#' @describeIn TopDownSet Summary statistics.
#'
#' Returns a `matrix`
#' with some statistics: number of fragments,
#' total/min/first quartile/median/mean/third quartile/maximum of
#' intensity values.
#'
## @param object `TopDownSet`
#' @param what `character`,
#' specifies whether `"conditions"` (columns; default)
#' or `"fragments"` (rows) should be summarized.
#' @aliases summary,TopDownSet-method
#' @export
setMethod("summary", "TopDownSet",
function(object, what=c("conditions", "fragments"), ...) {
what <- if (match.arg(what) == "conditions") { "columns" } else { "rows" }
callNextMethod(object=object, what=what)
})
#' @rdname TopDownSet-class
#' @name coerce,TopDownSet,MSnSet-method
#' @section Coercion:
#'
#' `as(object, "MSnSet"): Coerce an [TopDownSet-class] object into an
#' [MSnbase::MSnSet-class] object.
setAs("TopDownSet", "MSnSet", function(from) {
processing <- new(
"MSnProcess",
processing=from@processing,
files=from@files
)
msnset <- new(
"MSnSet",
exprs=as.matrix(from@assay),
phenoData=as(as(from@colData, "data.frame"), "AnnotatedDataFrame"),
featureData=as(as(from@rowViews, "data.frame"), "AnnotatedDataFrame"),
processingData=processing
)
## processingData are overwritten by ctor
msnset@processingData <- processing
if (validObject(msnset)) {
msnset
}
})
#' @rdname TopDownSet-class
#' @name coerce,TopDownSet,NCBSet-method
#' @section Coercion:
#'
#' `as(object, "NCBSet"): Coerce an [TopDownSet-class] object into an
#' [NCBSet-class] object.
setAs("TopDownSet", "NCBSet", function(from) {
assay <- .ncbMap(from)
ncb <- new(
"NCBSet",
rowViews=Views(
subject(from@rowViews),
start=1L, width=seq_len(nrow(assay)
),
names=rownames(assay)),
colData=from@colData,
assay=assay,
files=from@files,
processing=from@processing
)
colData(ncb)$AssignedIntensity <- Matrix::colSums(from@assay)
.atdsLogMsg(ncb, "Coerced TopDownSet into an NCBSet object")
})
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.