Skip to content

Commit

Permalink
Squeeze the IPosRanges class right below IntegerRanges in the class
Browse files Browse the repository at this point in the history
hierarchy. IRanges, IPos, NCList, and GroupingRanges are now direct
subclasses of IPosRanges instead of direct subclasses of IntegerRanges.
Views remains a direct subclass of IntegerRanges:
       Ranges
         ^
         |
    IntegerRanges
    ^           ^
    |           |
  Views     IPosRanges
            ^ ^   ^  ^
           /  |   |   \
          /   |   |    \
    IRanges IPos NCList GroupingRanges
  • Loading branch information
hpages committed Feb 8, 2018
1 parent e39b15a commit 62ee74a
Show file tree
Hide file tree
Showing 19 changed files with 212 additions and 224 deletions.
6 changes: 3 additions & 3 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Description: Provides efficient low-level and highly reusable S4
neighbors. Defines efficient list-like classes for storing,
transforming and aggregating large grouped data, i.e., collections
of atomic vectors and DataFrames.
Version: 2.13.22
Version: 2.13.23
Encoding: UTF-8
Author: H. Pagès, P. Aboyoun and M. Lawrence
Maintainer: Bioconductor Package Maintainer <maintainer@bioconductor.org>
Expand All @@ -28,8 +28,8 @@ Collate: range-squeezers.R
AtomicList-class.R
AtomicList-utils.R
Ranges-and-RangesList-classes.R
IntegerRanges-class.R
IntegerRanges-comparison.R
IPosRanges-class.R
IPosRanges-comparison.R
IntegerRangesList-class.R
IRanges-class.R
IRanges-constructor.R
Expand Down
9 changes: 5 additions & 4 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,13 @@ exportClasses(
FactorList, SimpleFactorList,

## Ranges-and-RangesList-classes.R:
Ranges, Pos,
Ranges, IntegerRanges, Pos,
RangesList, SimpleRangesList,
IntegerRangesList, SimpleIntegerRangesList,
PosList, SimplePosList,

## IntegerRanges-class.R:
IntegerRanges,
## IPosRanges-class.R:
IPosRanges,

## IntegerRangesList-class.R
IntegerRangesList, SimpleIntegerRangesList,
Expand Down Expand Up @@ -272,7 +273,7 @@ export(
showAsCell,
mstack,

## IntegerRanges-class.R:
## Ranges-and-RangesList-classes.R:
mid,
isNormal, whichFirstNotNormal,

Expand Down
8 changes: 4 additions & 4 deletions R/Grouping-class.R
Original file line number Diff line number Diff line change
Expand Up @@ -424,15 +424,15 @@ setMethod("high2low", "ANY",
###
### A GroupingRanges object represents a "block-grouping", that is, a
### grouping where each group is a block of adjacent elements in the original
### collection of objects. GroupingRanges objects support the IntegerRanges
### collection of objects. GroupingRanges objects support the IPosRanges
### API (e.g. start/end/width) in addition to the Grouping API.
###

setClass("GroupingRanges",
## We put IntegerRanges before Grouping so GroupingRanges objects inherit
## the "show" method for IntegerRanges objects instead of the method for
## We put IPosRanges before Grouping so GroupingRanges objects inherit
## the "show" method for IPosRanges objects instead of the method for
## Grouping objects.
contains=c("IntegerRanges", "Grouping"),
contains=c("IPosRanges", "Grouping"),
representation("VIRTUAL")
)

Expand Down
2 changes: 1 addition & 1 deletion R/IPos-class.R
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@


setClass("IPos",
contains=c("Pos", "IntegerRanges"),
contains=c("Pos", "IPosRanges"),
representation(
pos_runs="IRanges"
)
Expand Down
88 changes: 22 additions & 66 deletions R/IntegerRanges-class.R → R/IPosRanges-class.R
Original file line number Diff line number Diff line change
@@ -1,45 +1,35 @@
### =========================================================================
### IntegerRanges objects
### IPosRanges objects
### -------------------------------------------------------------------------
###
### IntegerRanges is a virtual class that serves as the base for all integer
### range containers. Conceptually integer ranges are closed, one-dimensional
### The ranges in an IPosRanges derivative are closed, one-dimensional
### intervals with integer end points and on the domain of integers.
###
### The direct IPosRanges subclasses defined in the IRanges package are:
### IRanges, IPos, NCList, and GroupingRanges.


setClass("IntegerRanges",
contains="Ranges",
setClass("IPosRanges",
contains="IntegerRanges",
representation("VIRTUAL")
)


### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### Getters/setters.
###

setMethod("update", "IntegerRanges",
function(object, ...)
as(update(as(object, "IRanges"), ...), class(object))
)


### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### Validity.
###

### The checking of the names(x) is taken care of by the validity method for
### Vector objects.

setValidity2("IntegerRanges", validate_Ranges)
setValidity2("IPosRanges", validate_Ranges)


### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### Coercion.
###

### Propagate the names.
setMethod("as.character", "IntegerRanges",
setMethod("as.character", "IPosRanges",
function(x)
{
if (length(x) == 0L)
Expand All @@ -56,18 +46,18 @@ setMethod("as.character", "IntegerRanges",

### The as.factor() generic doesn't have the ... argument so this method
### cannot support the 'ignore.strand' argument.
setMethod("as.factor", "IntegerRanges",
setMethod("as.factor", "IPosRanges",
function(x)
factor(as.character(x), levels=as.character(sort(unique(x))))
)

setMethod("as.matrix", "IntegerRanges",
setMethod("as.matrix", "IPosRanges",
function(x, ...)
matrix(data=c(start(x), width(x)), ncol=2,
dimnames=list(names(x), NULL))
)

.as.data.frame.IntegerRanges <- function(x, row.names=NULL, optional=FALSE, ...)
.as.data.frame.IPosRanges <- function(x, row.names=NULL, optional=FALSE, ...)
{
if (!(is.null(row.names) || is.character(row.names)))
stop("'row.names' must be NULL or a character vector")
Expand All @@ -81,14 +71,14 @@ setMethod("as.matrix", "IntegerRanges",
ans$names <- names(x)
ans
}
setMethod("as.data.frame", "IntegerRanges", .as.data.frame.IntegerRanges)
setMethod("as.data.frame", "IPosRanges", .as.data.frame.IPosRanges)


### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### show()
###

.make_naked_matrix_from_IntegerRanges <- function(x)
.make_naked_matrix_from_IPosRanges <- function(x)
{
x_len <- length(x)
x_mcols <- mcols(x)
Expand All @@ -104,7 +94,7 @@ setMethod("as.data.frame", "IntegerRanges", .as.data.frame.IntegerRanges)
ans
}

show_IntegerRanges <- function(x, margin="", print.classinfo=FALSE)
show_IPosRanges <- function(x, margin="", print.classinfo=FALSE)
{
x_class <- class(x)
x_len <- length(x)
Expand All @@ -116,14 +106,14 @@ show_IntegerRanges <- function(x, margin="", print.classinfo=FALSE)
x_nmc, " metadata ", ifelse(x_nmc == 1L, "column", "columns"),
":\n", sep="")
## S4Vectors:::makePrettyMatrixForCompactPrinting() assumes that 'x' is
## subsettable but not all IntegerRanges objects are (and if they are,
## subsetting them could be costly). However IRanges objects are assumed
## to be subsettable so if 'x' is not one then we turn it into one (this
## coercion is expected to work on any IntegerRanges object).
## subsettable but not all IPosRanges objects necesseraly are (and if they
## are, subsetting them could be costly). However IRanges objects are
## assumed to be subsettable so if 'x' is not one then we turn it into
## one (this coercion is expected to work on any IPosRanges object).
if (!is(x, "IRanges"))
x <- as(x, "IRanges", strict=FALSE)
out <- S4Vectors:::makePrettyMatrixForCompactPrinting(x,
.make_naked_matrix_from_IntegerRanges)
.make_naked_matrix_from_IPosRanges)
if (print.classinfo) {
.COL2CLASS <- c(
start="integer",
Expand All @@ -144,12 +134,12 @@ show_IntegerRanges <- function(x, margin="", print.classinfo=FALSE)
print(out, quote=FALSE, right=TRUE, max=length(out))
}

setMethod("show", "IntegerRanges",
setMethod("show", "IPosRanges",
function(object)
show_IntegerRanges(object, margin=" ", print.classinfo=TRUE)
show_IPosRanges(object, margin=" ", print.classinfo=TRUE)
)

setMethod("showAsCell", "IntegerRanges",
setMethod("showAsCell", "IPosRanges",
function(object)
{
if (length(object) == 0L)
Expand All @@ -159,37 +149,3 @@ setMethod("showAsCell", "IntegerRanges",
}
)


### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### isEmpty() and isNormal()
###
### All of them test an IntegerRanges object as a whole and return a single
### TRUE or FALSE.
###

setGeneric("isNormal", function(x, ...) standardGeneric("isNormal"))

setMethod("isNormal", "IntegerRanges",
function(x)
{
all_ok <- all(width(x) >= 1L)
if (length(x) >= 2)
all_ok <- all_ok && all(start(x)[-1L] - end(x)[-length(x)] >= 2L)
all_ok
}
)

setGeneric("whichFirstNotNormal",
function(x) standardGeneric("whichFirstNotNormal")
)

setMethod("whichFirstNotNormal", "IntegerRanges",
function(x)
{
is_ok <- width(x) >= 1L
if (length(x) >= 2)
is_ok <- is_ok & c(TRUE, start(x)[-1L] - end(x)[-length(x)] >= 2L)
which(!is_ok)[1L]
}
)

50 changes: 25 additions & 25 deletions R/IntegerRanges-comparison.R → R/IPosRanges-comparison.R
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
### =========================================================================
### Comparing and ordering ranges
### Comparing and ordering the ranges in IPosRanges derivatives
### -------------------------------------------------------------------------
###


setMethod("pcompareRecursively", "IntegerRanges", function(x) FALSE)
setMethod("pcompareRecursively", "IPosRanges", function(x) FALSE)


### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Expand All @@ -17,10 +17,10 @@ setMethod("pcompareRecursively", "IntegerRanges", function(x) FALSE)
### order.
###

setMethod("pcompare", c("IntegerRanges", "IntegerRanges"),
setMethod("pcompare", c("IPosRanges", "IPosRanges"),
function(x, y)
{
.Call2("IntegerRanges_pcompare",
.Call2("IPosRanges_pcompare",
start(x), width(x), start(y), width(y),
PACKAGE="IRanges")
}
Expand All @@ -41,12 +41,12 @@ rangeComparisonCodeToLetter <- function(code)
### match()
###

setMethod("match", c("IntegerRanges", "IntegerRanges"),
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 IntegerRanges objects ",
stop("\"match\" method for IPosRanges objects ",
"only accepts 'incomparables=NULL'")
## Equivalent to (but faster than):
## findOverlaps(x, table, type="equal", select="first")
Expand All @@ -62,7 +62,7 @@ setMethod("match", c("IntegerRanges", "IntegerRanges"),
### selfmatch()
###

setMethod("selfmatch", "IntegerRanges",
setMethod("selfmatch", "IPosRanges",
function(x, method=c("auto", "quick", "hash"))
selfmatchIntegerPairs(start(x), width(x), method=method)
)
Expand All @@ -71,27 +71,27 @@ setMethod("selfmatch", "IntegerRanges",
### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
### order() and related methods.
###
### is.unsorted(), order(), sort(), rank() on IntegerRanges derivatives are
### 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 IntegerRanges
### 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 IntegerRanges derivative
### 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).
###

.IntegerRanges_as_integer_pairs <- function(x)
.IPosRanges_as_integer_pairs <- function(x)
{
a <- start(x)
b <- width(x)
list(a, b)
}

setMethod("is.unsorted", "IntegerRanges",
setMethod("is.unsorted", "IPosRanges",
function(x, na.rm=FALSE, strictly=FALSE)
{
if (!identical(na.rm, FALSE))
warning("\"is.unsorted\" method for IntegerRanges objects ",
warning("\"is.unsorted\" method for IPosRanges objects ",
"ignores the 'na.rm' argument")
if (!isTRUEorFALSE(strictly))
stop("'strictly' must be TRUE of FALSE")
Expand All @@ -103,42 +103,42 @@ setMethod("is.unsorted", "IntegerRanges",
## 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 <- .IntegerRanges_as_integer_pairs(x)
pairs <- .IPosRanges_as_integer_pairs(x)
!S4Vectors:::sortedIntegerPairs(pairs[[1L]], pairs[[2L]],
strictly=strictly)
}
)

.order_IntegerRanges <- function(x, decreasing=FALSE)
.order_IPosRanges <- function(x, decreasing=FALSE)
{
if (!isTRUEorFALSE(decreasing))
stop("'decreasing' must be TRUE or FALSE")
pairs <- .IntegerRanges_as_integer_pairs(x)
pairs <- .IPosRanges_as_integer_pairs(x)
orderIntegerPairs(pairs[[1L]], pairs[[2L]], decreasing=decreasing)
}

### 'na.last' is pointless (IntegerRanges objects don't contain NAs) so is
### 'na.last' is pointless (IPosRanges derivatives don't contain NAs) so is
### ignored.
### 'method' is also ignored at the moment.
setMethod("order", "IntegerRanges",
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 IntegerRangesList object. The root of the
## problem is inconsistent defaults for 'na.last' between order() and
## sort(), as reported here:
## 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 IntegerRanges objects ",
# 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 IntegerRanges objects.
## All arguments in '...' are guaranteed to be IPosRanges derivatives.
args <- list(...)
if (length(args) == 1L)
return(.order_IntegerRanges(args[[1L]], decreasing))
order_args <- c(unlist(lapply(args, .IntegerRanges_as_integer_pairs),
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)
Expand Down
Loading

0 comments on commit 62ee74a

Please sign in to comment.