### =========================================================================
### windows()
### -------------------------------------------------------------------------
### windows() is a "parallel" version of window() for list-like objects. That
### is, it does 'mendoapply(window, x, start, end, width)' but uses a fast
### implementation.
setGeneric("windows", signature="x",
function(x, start=NA, end=NA, width=NA) standardGeneric("windows")
)
### NOT exported.
### Low-level utility used by various "windows" methods.
make_IRanges_from_windows_args <- function(x, start=NA, end=NA, width=NA)
{
x_eltNROWS <- elementNROWS(x)
if (!is(start, "IntegerRanges"))
return(solveUserSEW(x_eltNROWS, start=start, end=end, width=width))
if (!(identical(end, NA) && identical(width, NA)))
stop(wmsg("'end' or 'width' should not be specified or must be ",
"set to NA when 'start' is an IntegerRanges object"))
if (!is(start, "IRanges"))
start <- as(start, "IRanges")
ir <- S4Vectors:::V_recycle(start, x, x_what="start", skeleton_what="x")
if (any(start(ir) < 1L) || any(end(ir) > x_eltNROWS))
stop(wmsg("'start' contains out-of-bounds ranges"))
ir
}
setMethod("windows", "list_OR_List",
function(x, start=NA, end=NA, width=NA)
{
ir <- make_IRanges_from_windows_args(x, start, end, width)
if (length(x) == 0L)
return(x)
## -- Slow path (loops over the list elements of 'x') --
#for (k in seq_along(x))
# x[[k]] <- extractROWS(x[[k]], ir[k])
#return(x)
## -- Fast path --
## Unlist 'x' (preserving the inner names) and shift the ranges
## in 'ir'.
if (is.list(x)) {
unlisted_x <- bindROWS(x[[1L]], x[-1L])
} else {
unlisted_x <- unlist(x, use.names=FALSE)
}
offsets <- c(0L, end(PartitioningByEnd(x))[-length(x)])
ir <- shift(ir, shift=offsets)
## Subset.
unlisted_ans <- extractROWS(unlisted_x, ir)
## Relist.
ans_breakpoints <- cumsum(width(ir))
ans_partitioning <- PartitioningByEnd(ans_breakpoints, names=names(x))
ans <- as(relist(unlisted_ans, ans_partitioning), class(x))
## Propagate 'metadata(x)' and 'mcols(x)'.
if (is(x, "List")) {
metadata(ans) <- metadata(x)
mcols(ans) <- mcols(x, use.names=FALSE)
}
ans
}
)
### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### narrow()
###
### A recursive version of windows() i.e. on a list-like object it's
### equivalent to:
###
### mendoapply(narrow, x, start, end, width,
### MoreArgs=list(use.names=use.names))
###
setGeneric("narrow", signature="x",
function(x, start=NA, end=NA, width=NA, use.names=TRUE)
standardGeneric("narrow")
)
### Should operate recursively on an ordinary list or an IntegerRangesList,
### GenomicRangesList, DNAStrinSetList, or GAlignmentsList derivative.
### But not on an IRanges, GRanges, DNAStringSet, or GAlignments object
### where it's equivalent to windows().
setMethod("narrow", "ANY",
function(x, start=NA, end=NA, width=NA, use.names=TRUE)
{
call_windows <- is(x, "Ranges") ||
!is(x, "list_OR_List") ||
!pcompareRecursively(x)
if (call_windows) {
## We've reached a leaf in the recursion tree.
ans <- windows(x, start=start, end=end, width=width)
if (!S4Vectors:::normargUseNames(use.names))
names(ans) <- NULL
return(ans)
}
if (!is(start, "List"))
start <- as(start, "List")
start <- S4Vectors:::VH_recycle(start, x, "start", "x")
if (!is(width, "List"))
width <- as(width, "List")
width <- S4Vectors:::VH_recycle(width, x, "width", "x")
if (!is(end, "List"))
end <- as(end, "List")
end <- S4Vectors:::VH_recycle(end, x, "end", "x")
if (is(x, "CompressedList")) {
unlisted_start <- unlist(start, use.names=FALSE)
unlisted_end <- unlist(end, use.names=FALSE)
unlisted_width <- unlist(width, use.names=FALSE)
new_unlistData <- narrow(x@unlistData, start=unlisted_start,
end=unlisted_end,
width=unlisted_width,
use.names=use.names)
ans <- BiocGenerics:::replaceSlots(x, unlistData=new_unlistData,
check=FALSE)
return(ans)
}
mendoapply(narrow, x, start, end, width,
MoreArgs=list(use.names=use.names))
}
)
### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### heads() and tails()
###
### These are just convenience wrappers around windows().
###
### They do 'mendoapply(head, x, n)' and 'mendoapply(tail, x, n)',
### respectively, but use a fast implementation.
###
.normarg_n <- function(n, x_eltNROWS)
{
if (!is.numeric(n))
stop("'n' must be an integer vector")
if (!is.integer(n))
n <- as.integer(n)
if (any(is.na(n)))
stop("'n' cannot contain NAs")
n <- pmin(x_eltNROWS, n)
neg_idx <- which(n < 0L)
if (length(neg_idx) != 0L)
n[neg_idx] <- pmax(n[neg_idx] + x_eltNROWS[neg_idx], 0L)
n
}
heads <- function(x, n=6L)
{
x_eltNROWS <- unname(elementNROWS(x))
n <- .normarg_n(n, x_eltNROWS)
windows(x, start=1L, width=n)
}
tails <- function(x, n=6L)
{
x_eltNROWS <- unname(elementNROWS(x))
n <- .normarg_n(n, x_eltNROWS)
windows(x, end=x_eltNROWS, width=n)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.