###########################################################################/**
# @set "class=AbstractCBS"
# @RdocDocumentation "Restructuring AbstractCBS objects"
# @alias RestructPSCBS
#
# \description{
# This page describes available methods for restructuring an
# @see "AbstractCBS" object.
#
# \itemize{
# \item @seemethod "extractChromosomes" /
# @seemethod "extractChromosome"
# - Extracts an @see "AbstractCBS" with the specified chromosomes.
#
# \item @seemethod "extractSegments" /
# @seemethod "extractSegment"
# - Extracts an @see "AbstractCBS" with the specified segments.
#
# \item @seemethod "extractRegions" /
# @seemethod "extractRegion"
# - Extracts an @see "AbstractCBS" with the specified regions
# each of a certain size, where a region is defined as a
# connected set of segments.
#
# \item @seemethod "dropRegions" /
# @seemethod "dropRegion"
# - Drops specified regions and returns an @see "AbstractCBS"
# without them.
#
# \item @seemethod "dropChangePoint" /
# @seemethod "mergeTwoSegments"
# - Drops a change point by merging two neighboring segments
# and recalculates the statistics for the merged segment
# before returning an @see "AbstractCBS".
#
# \item @seemethod "dropChangePoints"
# - Drops zero or more change points
# and recalculates the segment statistics
# before returning an @see "AbstractCBS".
#
# \item @seemethod "mergeThreeSegments"
# - Merges a segment with its two flanking segments
# and recalculates the statistics for the merged segment
# before returning an @see "AbstractCBS".
# }
#
# All of the above methods are implemented for @see "CBS" and
# @see "PairedPSCBS" objects.
# }
#
# @author "HB"
#
# \seealso{
# @seeclass
# }
#
# @keyword internal
#*/###########################################################################
setMethodS3("renameChromosomes", "AbstractCBS", function(fit, from, to, ...) {
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Validate arguments
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Argument 'from' & 'to':
from <- Arguments$getIntegers(from, disallow=c("NaN", "Inf"))
n <- length(from)
to <- Arguments$getIntegers(to, disallow=c("NaN", "Inf"), length=c(n,n))
# Nothing to do?
if (n == 0) {
return(fit)
}
data <- getLocusData(fit)
segs <- getSegments(fit, splitters=TRUE, simplify=FALSE)
knownSegments <- fit$params$knownSegments
for (cc in seq_len(n)) {
chr <- from[cc]
chrN <- to[cc]
data$chromosome[data$chromosome == chr] <- chrN
segs$chromosome[segs$chromosome == chr] <- chrN
knownSegments$chromosome[knownSegments$chromosome == chr] <- chrN
} # for (cc ...)
fit <- setLocusData(fit, data)
fit <- setSegments(fit, segs)
fit$params$knownSegments <- knownSegments
fit
}, protected=TRUE) # renameChromosomes()
setMethodS3("extractChromosomes", "AbstractCBS", abstract=TRUE, protected=TRUE)
setMethodS3("extractChromosome", "AbstractCBS", function(x, chromosome, ...) {
# To please R CMD check
this <- x
# Argument 'chromosome':
chromosome <- Arguments$getInteger(chromosome, disallow=c("NaN", "Inf"))
extractChromosomes(this, chromosomes=chromosome, ...)
}, protected=TRUE)
setMethodS3("extractSegments", "AbstractCBS", abstract=TRUE, protected=TRUE)
setMethodS3("extractSegment", "AbstractCBS", function(this, idx, ...) {
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Validate arguments
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Argument 'region':
idx <- Arguments$getIndex(idx, max=nbrOfSegments(this, splitters=TRUE))
extractSegments(this, idxs=idx, ...)
}, private=TRUE) # extractSegment()
setMethodS3("extractRegions", "AbstractCBS", function(this, regions, H=1, ..., verbose=FALSE) {
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Validate arguments
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
nbrOfSegments <- nbrOfSegments(this, splitters=TRUE)
# Argument 'regions':
regions <- Arguments$getIndices(regions, max=nbrOfSegments)
# Argument 'H':
H <- Arguments$getInteger(H, range=c(0,Inf))
# Argument 'verbose':
verbose <- Arguments$getVerbose(verbose)
if (verbose) {
pushState(verbose)
on.exit(popState(verbose))
}
verbose && enter(verbose, "Extract regions of a certain length")
verbose && cat(verbose, "Left-most segments of regions to be extracted:")
verbose && str(verbose, regions)
verbose && cat(verbose, "Number of segments in each region: ", H)
# Identify segments to keep
Hs <- seq_len(H)
regions <- regions - 1L
regions <- as.list(regions)
segments <- lapply(regions, FUN=function(region) region + Hs)
segments <- unlist(segments, use.names=FALSE)
segments <- sort(unique(segments))
verbose && cat(verbose, "Final set of segments to be extracted:")
verbose && str(verbose, segments)
res <- extractSegments(this, idxs=segments, ...)
verbose && exit(verbose)
res
}, protected=TRUE) # extractRegions()
setMethodS3("extractRegion", "AbstractCBS", function(this, region, ...) {
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Validate arguments
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Argument 'region':
region <- Arguments$getIndex(region, max=nbrOfSegments(this, splitters=TRUE))
extractRegions(this, regions=region, ...)
}, private=TRUE) # extractRegion()
###########################################################################/**
# @RdocMethod mergeTwoSegments
# @aliasmethod dropChangePoint
#
# @title "Merge two neighboring segments"
#
# \description{
# @get "title" into one segment, which is done by dropping their
# common change point and recalculating the segment statistics.
# }
#
# @synopsis
#
# \arguments{
# \item{...}{Not used.}
# }
#
# \value{
# Returns an @see "AbstractCBS" of the same class with one less segment.
# }
#
# @author "HB"
#
# \seealso{
# To merge a segment and its two flanking segments, see
# @seemethod "mergeThreeSegments".
# To drop regions (a connected set of segments)
# see @seemethod "dropRegions".
# @seeclass
# }
#*/###########################################################################
setMethodS3("mergeTwoSegments", "AbstractCBS", abstract=TRUE, protected=TRUE)
setMethodS3("dropChangePoint", "AbstractCBS", function(fit, idx, ...) {
# Argument 'idx':
## max <- nbrOfChangePoints(fit, splitters=TRUE, ...)
max <- nbrOfSegments(fit, splitters=TRUE, ...) - 1L
idx <- Arguments$getIndex(idx, max=max)
mergeTwoSegments(fit, left=idx, ...)
}, protected=TRUE)
###########################################################################/**
# @RdocMethod dropChangePoints
#
# @title "Drops zero or more change points"
#
# \description{
# @get "title", which is done by dropping one change point at the
# time using @seemethod "dropChangePoint"
# and recalculating the segment statistics at the end.
#
# \emph{NOTE: This method only works if there is only one chromosome.}
# }
#
# @synopsis
#
# \arguments{
# \item{idxs}{An @integer @vector specifying the change points to be dropped.}
# \item{update}{If @TRUE, segment statistics are updated.}
# \item{...}{Other arguments passed to @seemethod "dropChangePoint"
# and @seemethod "updateMeans".}
# }
#
# \value{
# Returns an @see "AbstractCBS" of the same class with
# \code{length(idxs)} segments.
# }
#
# @author "HB"
#
# \seealso{
# @seeclass
# }
#*/###########################################################################
setMethodS3("dropChangePoints", "AbstractCBS", function(fit, idxs, update=TRUE, ...) {
# Assert that there is only one chromosome
chrs <- getChromosomes(fit)
if (length(chrs) > 1) {
stop("dropChangePoints() only support single-chromosome data: ", hpaste(chrs))
}
# Argument 'idxs':
## max <- nbrOfChangePoints(fit, splitters=TRUE, ...)
max <- nbrOfSegments(fit, splitters=TRUE, ...) - 1L
idxs <- Arguments$getIndices(idxs, max=max)
# Drop change points one by one
idxs <- unique(idxs)
idxs <- sort(idxs, decreasing=TRUE)
for (ii in seq_along(idxs)) {
idx <- idxs[ii]
updateI <- update && (ii == length(idxs))
fit <- dropChangePoint(fit, idx=idx, update=updateI, ...)
}
# Update segment statistics?
if (update) {
fit <- updateMeans(fit, ...)
}
fit
}, protected=TRUE)
###########################################################################/**
# @RdocMethod mergeThreeSegments
#
# @title "Merge a segment and its two flanking segments"
#
# \description{
# @get "title" into one segment, and recalculating the segment statistics.
# }
#
# @synopsis
#
# \arguments{
# \item{middle}{An @integer specifying the three segments
# (middle-1, middle, middle+1) to be merged.}
# \item{...}{Additional arguments passed to @seemethod "mergeTwoSegments".}
# }
#
# \value{
# Returns an @see "AbstractCBS" of the same class with two less segment.
# }
#
# @author "HB"
#
# \seealso{
# Internally @seemethod "mergeTwoSegments" is used.
# @seeclass
# }
#*/###########################################################################
setMethodS3("mergeThreeSegments", "AbstractCBS", function(fit, middle, ...) {
# Argument 'middle':
S <- nbrOfSegments(fit, splitters=TRUE)
middle <- Arguments$getIndex(middle, range=c(2L, S))
# Assert that the three segments are on the same chromosome
idxs <- middle + c(-1L, 0L, +1L)
fitT <- extractSegments(fit, idxs)
chrs <- getChromosomes(fitT)
if (length(chrs) != 1L) {
stop("Argument 'middle' specifies a segment that is at the very end of a chromosome: ", middle)
}
fitT <- NULL # Not needed anymore
fit <- mergeTwoSegments(fit, left=middle, ...)
fit <- mergeTwoSegments(fit, left=middle-1L, ...)
fit
}) # mergeThreeSegments()
###########################################################################/**
# @RdocMethod dropRegions
# @aliasmethod dropRegion
#
# @title "Drops chromosomal regions (a connected set of segments)"
#
# \description{
# @get "title" each of a certain size (number of segments).
# \emph{None of the statistics are recalculated}.
# }
#
# @synopsis
#
# \arguments{
# \item{regions}{An @integer @vector of length R specifying the indices
# of the left most segment in each of the R regions to be dropped.}
# \item{H}{A non-negative @integer specifying the size of each region,
# i.e. the number of segments per region.}
# \item{...}{Additional arguments passed to @seemethod "extractRegions".}
# \item{asMissing}{If @TRUE, dropped segments are replaced by missing values,
# otherwise they are truly dropped.}
# \item{verbose}{A @logical or a @see "R.utils::Verbose" object.}
# }
#
# \value{
# Returns an @see "AbstractCBS" object of the same class with (at most)
# R*H segments dropped.
# If some regions overlap (share segments), then fewer than R*H segments
# are dropped.
# }
#
# @author "HB"
#
# \seealso{
# Internally @seemethod "extractRegions" is used.
# See also @seemethod "dropChangePoint" and @seemethod "mergeTwoSegments".
# @seeclass
# }
#*/###########################################################################
setMethodS3("dropRegions", "AbstractCBS", function(this, regions, H=1, ..., asMissing=FALSE, verbose=FALSE) {
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Validate arguments
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
nbrOfSegments <- nbrOfSegments(this, splitters=TRUE)
# Argument 'regions':
regions <- Arguments$getIndices(regions, max=nbrOfSegments)
# Argument 'H':
H <- Arguments$getInteger(H, range=c(0,Inf))
# Argument 'asMissing':
asMissing <- Arguments$getLogical(asMissing)
# Argument 'verbose':
verbose <- Arguments$getVerbose(verbose)
if (verbose) {
pushState(verbose)
on.exit(popState(verbose))
}
verbose && enter(verbose, "Dropping regions of a certain length")
verbose && cat(verbose, "Left-most segments of regions to be dropped:")
verbose && str(verbose, regions)
verbose && cat(verbose, "Number of segments in each region: ", H)
# Nothing to do?
if (H == 0) {
verbose && cat(verbose, "Nothing to do. No segments will be dropped.")
verbose && exit(verbose)
return(this)
}
# Identify segments to drop
Hs <- seq_len(H)
regions <- regions - 1L
regions <- as.list(regions)
regions <- lapply(regions, FUN=function(region) region + Hs)
regions <- unlist(regions, use.names=FALSE)
regions <- sort(unique(regions))
verbose && cat(verbose, "Final set of segments to be dropped:")
verbose && str(verbose, regions)
# Identify segments to keep
allRegions <- seq_len(nbrOfSegments)
keepSegments <- setdiff(allRegions, regions)
verbose && cat(verbose, "Final set of segments to be kept:")
verbose && str(verbose, keepSegments)
dropped <- extractRegions(this, regions=regions, ...)
res <- this
if (length(regions) > 0) {
if (asMissing) {
segs <- getSegments(res, splitters=TRUE)
pattern <- "(chromosome|id|start|end)$"
# TODO/AD HOC: Should be class specific /HB 2011-10-17
pattern <- "(chromosome|id)$"
excl <- grep(pattern, colnames(segs), ignore.case=TRUE, invert=TRUE)
segs[regions,excl] <- NA
res$output <- segs
# TODO/AD HOC: Should be class specific /HB 2011-10-17
for (ff in grep("segRows", names(res), ignore.case=TRUE, value=TRUE)) {
res[[ff]][regions,] <- NA
}
} else {
res <- extractRegions(res, regions=keepSegments, ...)
}
}
res$dropped <- dropped
# Sanity check
if (asMissing) {
.stop_if_not(nbrOfSegments(res, splitters=TRUE) == nbrOfSegments(this, splitters=TRUE))
} else {
.stop_if_not(nbrOfSegments(res, splitters=TRUE) + length(regions) == nbrOfSegments(this, splitters=TRUE))
}
verbose && exit(verbose)
res
}, protected=TRUE)
setMethodS3("dropRegion", "AbstractCBS", function(fit, region, ...) {
# Argument 'region':
region <- Arguments$getIndex(region)
dropRegions(fit, regions=region, ...)
}, protected=TRUE)
setMethodS3("shiftTCN", "AbstractCBS", abstract=TRUE, protected=TRUE)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.