Skip to content

Commit e6df994

Browse files
committed
Fixes comparisons to be atomic; adds pcompare support; update man and DESCRIPTION
1 parent 30f1a48 commit e6df994

File tree

4 files changed

+112
-28
lines changed

4 files changed

+112
-28
lines changed

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Description: Provides memory efficient S4 classes for storing sequences
55
biocViews: Infrastructure, DataRepresentation
66
URL: https://bioconductor.org/packages/XVector
77
BugReports: https://github.com/Bioconductor/XVector/issues
8-
Version: 0.47.1
8+
Version: 0.47.2
99
License: Artistic-2.0
1010
Encoding: UTF-8
1111
Author: Hervé Pagès and Patrick Aboyoun

R/SharedVector-class.R

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,3 +396,7 @@ setMethod("!=", signature(e1="SharedVector", e2="SharedVector"),
396396
function(e1, e2) address(e1@xp) != address(e2@xp)
397397
)
398398

399+
setMethod("<=", signature(e1="SharedVector", e2="SharedVector"),
400+
function(e1, e2) address(e1@xp) <= address(e2@xp)
401+
)
402+

R/XVector-class.R

Lines changed: 55 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,54 @@ setMethod("bindROWS", "XVector", .concatenate_XVector_objects)
169169
### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
170170
### Equality
171171
###
172-
### order() and sameAsPreviousROW are required to make XVector compatible with
173-
### the equality functions defined in S4Vectors
172+
173+
.XVector.equal <- function(x, y)
174+
{
175+
if (class(x) != class(y) || x@length != y@length)
176+
return(FALSE)
177+
ans <- !SharedVector.compare(x@shared, x@offset + 1L,
178+
y@shared, y@offset + 1L,
179+
x@length)
180+
as.logical(ans)
181+
}
182+
183+
.XVector.lt_or_equal <- function(x, y)
184+
{
185+
if (class(x) != class(y) || x@length != y@length)
186+
return(FALSE)
187+
ans <- SharedVector.compare(x@shared, x@offset + 1L,
188+
y@shared, y@offset + 1L,
189+
x@length)
190+
ans <= 0
191+
}
192+
193+
setMethod("==", signature(e1="XVector", e2="XVector"),
194+
function(e1, e2) .XVector.equal(e1, e2)
195+
)
196+
197+
setMethod("<=", signature(e1="XVector", e2="XVector"),
198+
function(e1, e2) .XVector.lt_or_equal(e1, e2)
199+
)
200+
201+
setMethod("==", signature(e1="XVector", e2="ANY"),
202+
function(e1, e2) e1 == as(e2, class(e1))
203+
)
204+
# setMethod("==", signature(e1="ANY", e2="XVector"),
205+
# function(e1, e2) e2 == e1
206+
# )
207+
208+
setMethod("<=", signature(e1="XVector", e2="ANY"),
209+
function(e1, e2) e1 <= as(e2, class(e1))
210+
)
211+
setMethod("<=", signature(e1="ANY", e2="XVector"),
212+
function(e1, e2) !(e2 > e1)
213+
)
214+
215+
### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
216+
### Parallel comparison
217+
###
218+
### order() and sameAsPreviousROW make XVector compatible with pcompare
219+
### as defined in S4Vectors
174220

175221
.XVector.order <- function(x, decreasing=FALSE){
176222
SharedVector.order(x@shared, decreasing)
@@ -183,9 +229,10 @@ setMethod("order", "XVector",
183229
.XVector.order(x, decreasing)
184230
} else {
185231
args <- unname(args)
186-
do.call(order, c(args, list(na.last=na.last,
187-
decreasing=decreasing,
188-
method=method)))
232+
## do.call("order", args) doesn't work here
233+
## I can't figure out why...this produces the same result
234+
lapply(args, order,
235+
na.last=na.last, decreasing=decreasing, method=method)
189236
}
190237
}
191238
)
@@ -200,30 +247,11 @@ setMethod("order", "XVector",
200247
}
201248
setMethod("sameAsPreviousROW", "XVector", .XVector.sameAsPreviousROW)
202249

203-
## These methods are defined so that the XVector argument comes first
250+
## This methods are defined so that the XVector argument comes first
204251
## this matters because of how S4Vectors::pcompare is defined; it attempts
205252
## to coerce the second argument to a list and then concatenate, which can
206253
## cause weird behavior if the first element is an atomic vector and the
207254
## second is an XVector object.
208-
setMethod("==", signature(e1="ANY", e2="XVector"),
209-
function(e1, e2) { pcompare(e2, e1) == 0 }
255+
setMethod("pcompare", signature(x="ANY", y="XVector"),
256+
function(x, y) -1*callNextMethod(y, x)
210257
)
211-
212-
setMethod("<=", signature(e1="ANY", e2="XVector"),
213-
function(e1, e2) { pcompare(e2, e1) >= 0L }
214-
)
215-
216-
.XVector.equal <- function(x, y)
217-
{
218-
if (class(x) != class(y) || x@length != y@length)
219-
return(FALSE)
220-
ans <- !SharedVector.compare(x@shared, x@offset + 1L,
221-
y@shared, y@offset + 1L,
222-
x@length)
223-
as.logical(ans)
224-
}
225-
226-
setMethod("==", signature(e1="XVector", e2="XVector"),
227-
function(e1, e2) .XVector.equal(e1, e2)
228-
)
229-

man/XVector-class.Rd

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@
1515
\alias{as.numeric,XVector-method}
1616
\alias{show,XVector-method}
1717
\alias{==,XVector,XVector-method}
18+
\alias{<=,XVector,XVector-method}
19+
\alias{>=,XVector,XVector-method}
20+
\alias{<,XVector,XVector-method}
21+
\alias{>,XVector,XVector-method}
22+
\alias{!=,XVector,XVector-method}
23+
\alias{pcompare,XVector,XVector-method}
24+
\alias{order,XVector,XVector-method}
1825

1926
% XRaw class, functions and methods:
2027
\alias{class:XRaw}
@@ -80,6 +87,31 @@
8087
data when a linear subsequence needs to be extracted.
8188
}
8289

90+
\section{Comparison operations on XVector objects}{
91+
Unlike the R's base vectors, comparing two XVector objects works \emph{atomically} -- that is, it doesn't compare element-by-element, but rather the two vectors as a whole. Thus, the return value of a comparison between two XVector objects will always be a single logical value. Comparison between an XVector and a base vector is performed by coercing the base vector to the same type as the XVector prior to comparison (potentially throwing an error if the comparison is impossible!).
92+
93+
For element-wise comparison, the following are provided:
94+
95+
\describe{
96+
\item{\code{pcompare(x,y)}:}{
97+
Compares the elements of two vectors \code{x} and \code{y} in an
98+
element-wise fashion. If \code{length(x) != length(y)}, the shorter
99+
length vector is recycled to the length of the longer. Returns a
100+
vector where the i'th element is:
101+
\itemize{
102+
\item negative if \code{x[i] < y[i]}
103+
\item zero if \code{x[i] == y[i]}
104+
\item positive if \code{x[i] > y[i]}
105+
} More details are
106+
available in the help page available via S4Vectors:
107+
\code{\link[S4Vectors]{pcompare}}.
108+
}
109+
\item{\code{order(x, decreasing=FALSE)}:}{
110+
Returns a permutation vector that rearranges its first argument into ascending or descending order, similar to \code{\link[base]{order}}. Additional argument \code{na.last} is ignored, since XVector objects do not allow \code{NA} values. \code{method} is
111+
}
112+
}
113+
}
114+
83115
\section{Additional Subsetting operations on XVector objects}{
84116
In the code snippets below, \code{x} is an XVector object.
85117
@@ -168,6 +200,26 @@
168200

169201
x3[length(x3):1]
170202
x3[length(x3):1, drop=FALSE]
203+
204+
## ---------------------------------------------------------------------
205+
## C. Comparing XVector OBJECTS
206+
## ---------------------------------------------------------------------
207+
xv <- XInteger(5, 1:5)
208+
yv <- XInteger(5, 5:1)
209+
210+
## Comparison between XVector objects is ATOMIC
211+
xv == yv ## FALSE
212+
xv < yv ## TRUE
213+
214+
## Element-wise comparison uses pcompare
215+
pcompare(xv, yv) ## -1 -1 0 1 1
216+
pcompare(yv, xv) ## 1 1 0 -1 -1
217+
pcompare(xv, 5:1) ## equivalent to pcompare(xv, yv)
218+
219+
## Convert to T/F values by comparing against zero:
220+
pcompare(xv, yv) < 0 ## element-wise xv < yv
221+
pcomapre(xv, yv) >= 0 ## element-size xv >= yv
222+
171223
}
172224

173225
\keyword{methods}

0 commit comments

Comments
 (0)