### =========================================================================
### Comparing and ordering the ranges in IPosRanges derivatives
### -------------------------------------------------------------------------
###
setMethod("pcompareRecursively", "IPosRanges", function(x) FALSE)
### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### pcompare()
###
### Ranges are ordered by starting position first and then by width.
### This way, the space of ranges is totally ordered.
### This "pcompare" method returns one of the 13 predefined codes (>= -6 and
### <= 6) described in the man page. The signs of those codes reflect this
### order.
###
setMethod("pcompare", c("IPosRanges", "IPosRanges"),
function(x, y)
{
.Call2("C_pcompare_IPosRanges",
start(x), width(x), start(y), width(y),
PACKAGE="IRanges")
}
)
rangeComparisonCodeToLetter <- function(code)
{
if (!is.integer(code))
stop("'code' must be an integer vector")
code <- code + 7L
code[code < 1L | 14L < code] <- 14L
levels <- c(letters[1:13], "X")
structure(code, levels=levels, class="factor")
}
### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### match()
###
setMethod("match", c("IPosRanges", "IPosRanges"),
function(x, table, nomatch=NA_integer_, incomparables=NULL,
method=c("auto", "quick", "hash"))
{
if (!is.null(incomparables))
stop("\"match\" method for IPosRanges objects ",
"only accepts 'incomparables=NULL'")
## Equivalent to (but faster than):
## findOverlaps(x, table, type="equal", select="first")
## except when 'x' or 'table' contain empty ranges.
matchIntegerPairs(start(x), width(x),
start(table), width(table),
nomatch=nomatch, method=method)
}
)
### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### selfmatch()
###
setMethod("selfmatch", "IPosRanges",
function(x, method=c("auto", "quick", "hash"))
selfmatchIntegerPairs(start(x), width(x), method=method)
)
### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### order() and related methods.
###
### is.unsorted(), order(), sort(), rank() on IPosRanges derivatives are
### consistent with the order implied by pcompare().
### is.unsorted() is a quick/cheap way of checking whether an IPosRanges
### derivative is already sorted, e.g., called prior to a costly sort.
### sort() and rank() will work out-of-the-box on an IPosRanges derivative
### thanks to the method for List objects (which delegates to the method for
### Vector objects).
###
.IPosRanges_as_integer_pairs <- function(x)
{
a <- start(x)
b <- width(x)
list(a, b)
}
setMethod("is.unsorted", "IPosRanges",
function(x, na.rm=FALSE, strictly=FALSE)
{
if (!identical(na.rm, FALSE))
warning("\"is.unsorted\" method for IPosRanges objects ",
"ignores the 'na.rm' argument")
if (!isTRUEorFALSE(strictly))
stop("'strictly' must be TRUE of FALSE")
## It seems that creating the integer pairs below is faster when
## 'x' is already sorted (TODO: Investigate why). Therefore, and
## somewhat counterintuitively, is.unsorted() can be faster when 'x'
## is already sorted (which, in theory, is the worst-case scenario
## because S4Vectors:::sortedIntegerPairs() will then need to take a
## full walk on 'x') than when it is unsorted (in which case
## S4Vectors:::sortedIntegerPairs() might stop walking on 'x' after
## checking its first 2 elements only -- the best-case scenario).
pairs <- .IPosRanges_as_integer_pairs(x)
!S4Vectors:::sortedIntegerPairs(pairs[[1L]], pairs[[2L]],
strictly=strictly)
}
)
.order_IPosRanges <- function(x, decreasing=FALSE)
{
if (!isTRUEorFALSE(decreasing))
stop("'decreasing' must be TRUE or FALSE")
pairs <- .IPosRanges_as_integer_pairs(x)
orderIntegerPairs(pairs[[1L]], pairs[[2L]], decreasing=decreasing)
}
### 'na.last' is pointless (IPosRanges derivatives don't contain NAs) so is
### ignored.
### 'method' is also ignored at the moment.
setMethod("order", "IPosRanges",
function(..., na.last=TRUE, decreasing=FALSE,
method=c("auto", "shell", "radix"))
{
## Turn off this warning for now since it triggers spurious warnings
## when calling sort() on an IPosRangesList derivative. The root of
## the problem is inconsistent defaults for 'na.last' between order()
## and sort(), as reported here:
## https://stat.ethz.ch/pipermail/r-devel/2015-November/072012.html
#if (!identical(na.last, TRUE))
# warning("\"order\" method for IPosRanges objects ",
# "ignores the 'na.last' argument")
if (!isTRUEorFALSE(decreasing))
stop("'decreasing' must be TRUE or FALSE")
## All arguments in '...' are guaranteed to be IPosRanges derivatives.
args <- list(...)
if (length(args) == 1L)
return(.order_IPosRanges(args[[1L]], decreasing))
order_args <- c(unlist(lapply(args, .IPosRanges_as_integer_pairs),
recursive=FALSE, use.names=FALSE),
list(na.last=na.last, decreasing=decreasing))
do.call(order, order_args)
}
)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.