The between and outside operators are used to check, whether a vector of given values x lie within a defined range (or outside respectively). The values can be numbers, text or dates. Ordered factors are supported.

x %()% rng
x %(]% rng
x %[)% rng
x %[]% rng

x %][% rng
x %](% rng
x %)[% rng
x %)(% rng

x %:% rng
x %::% rng

Arguments

x

is a variable with at least ordinal scale, usually a numeric value, but can be an ordered factor or a text as well. Texts would be treated alphabetically.

rng

a vector of two values or a matrix with 2 columns, defining the minimum and maximum of the range for x.
If rng is a matrix, x or rng will be recycled.

Details

The "BETWEEN" operators basically combine two conditional statements into one and simplify the query process.
They are merely a wrapper for: x >= rng[1] & x <= rng[2], where the round bracket ( means strictly greater (>) and the square bracket [ means greater or equal (>=). Numerical values of x will be handled by C-code, which is significantly faster than two comparisons in R (especially when x is huge). .
%][% is the negation of %()%, meaning all values lying outside the given range. Elements on the limits will return TRUE.

Both arguments, x and rng, will be recycled to the highest dimension, which is either the length of the vector (x) or the number of rows of the matrix (rng).
See also the routines used to check, whether two ranges overlap (Overlap, Interval).

%:% returns all the elements of a vector between the (first found) element rng[1] and rng[2]. If no match is found it returns NA. If rng[2] occurs before rng[1] in the vector the elements will be returned in reverse order (which is the same behaviour as the : operator).
%::% does the same in greedy mood. It uses the first match for from and the last match for to.

Value

A logical vector of the same length as x.

Author

Andri Signorell <andri@signorell.net> based on C-code by Kevin Ushey <kevinushey@gmail.com>

Examples

x <- 1:9
x %[]% c(3,5)
#> [1] FALSE FALSE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE

# outside
x <- 1:9
x %][% c(3,5)
#> [1]  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE

c(x,NA) %[]% c(3,5)
#>  [1] FALSE FALSE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE    NA

x %(]% c(3,5)
#> [1] FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE

# no result when from > to:
x %[]% c(5,3)
#> [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
x %(]% c(5,5)
#> [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

# no problem:
ordered(x) %[]% c(3,5)
#> [1] FALSE FALSE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE

# not meaningful:
factor(x) %[]% c(3,5)
#> [1] NA NA NA NA NA NA NA NA NA

# characters
letters[letters %(]% c("d","h")]
#> [1] "e" "f" "g" "h"

data(d.pizza)
x <- levels(d.pizza$driver)
x %[]% c("C","G")
#> [1] FALSE  TRUE  TRUE  TRUE FALSE FALSE FALSE

# select diamonds with a price between 2400 and 2510
data(d.diamonds)
d.diamonds[d.diamonds$price %[]% c(2400,2510),]
#>     index carat colour clarity cut certification polish symmetry price
#> 116   116  1.05      I      I1   F           GIA      G        G  2413
#> 117   117  1.09      K      I1   X           GIA      G        G  2427
#> 118   118  1.14      L      I2   X           GIA      V        V  2437
#> 119   119  1.11      G      I2   X           GIA      G        G  2438
#> 120   120  1.21      K     SI3   F           EGL      G        G  2446
#> 181   181  1.03      H      I1   X           EGL      G        G  2451
#> 182   182  1.00      J     SI2   G           EGL      G        V  2452
#> 183   183  1.15      J     SI3   G           EGL      G        G  2467
#> 184   184  1.01      J     SI2   I           EGL      V        X  2476
#> 185   185  1.00      E      I1   F           EGL      V        G  2486
#> 186   186  1.12      K      I1   F           GIA      G        F  2493
#> 187   187  1.01      E      I2   X           GIA      G        G  2495
#>     wholesaler
#> 116          B
#> 117          B
#> 118          B
#> 119          B
#> 120          B
#> 181          B
#> 182          B
#> 183          B
#> 184          B
#> 185          B
#> 186          B
#> 187          B

# use it with an ordered factor and select all diamonds with
#   symmetry between G (included) and X (excluded).
mean(d.diamonds[d.diamonds$symmetry %[)% c("G","X"),"price"])
#> [1] 1651.03


# use multiple ranges
2 %[]% cbind(1:4,2:5)
#> [1]  TRUE  TRUE FALSE FALSE

# both arguments are recycled
c(2,3) %[]% cbind(1:4,2:5)
#> [1]  TRUE  TRUE FALSE FALSE


# between operator for vector positions
set.seed(4)
(x <- sample(LETTERS, size=10, replace=TRUE))
#>  [1] "X" "K" "S" "C" "G" "L" "S" "V" "U" "Z"
# [1] "X" "K" "S" "C" "G" "L" "S" "V" "U" "Z"

# return all elements between "S" and "L" 
x %:% c("S","L")
#> [1] "S" "C" "G" "L"
# [1] "S" "C" "G" "L"
 
x %:% c("S","A")
#> [1] "S" "C" "G" "L" "S" "V" "U" "Z"
# [1] "S" "C" "G" "L" "S" "V" "U" "Z"
 
x %:% c("A","S")
#> [1] "X" "K" "S"
# [1] "X" "K" "S"

# reverted matches return the elements in reverse order
x %:% c("G","X")
#> [1] "G" "C" "S" "K" "X"
# [1] "G" "C" "S" "K" "X"

# no match results in NA
x %:% c("Y","B")
#>  [1] "X" "K" "S" "C" "G" "L" "S" "V" "U" "Z"

(x <- c("B", "A", "X", "K", "S", "K", "G", "L", "K", "V", "K", "Z"))
#>  [1] "B" "A" "X" "K" "S" "K" "G" "L" "K" "V" "K" "Z"
# lazy
x %:% c("A", "K")
#> [1] "A" "X" "K"
# greedy
x %::% c("A", "K")
#>  [1] "A" "X" "K" "S" "K" "G" "L" "K" "V" "K"