Supplementary utilities and extensions to R that are idiomatic in
style.
Install the latest release of suppr from CRAN:
install.packages("suppr")
You can install the development version of suppr from GitHub:
# install.packages("pak")
# pak::pak("LJ-Jenkins/suppr")
install.packages("suppr", repos = c('https://lj-jenkins.r-universe.dev', 'https://cloud.r-project.org'))
suppr provides miscellaneous supplementary functions for R: some are
simple wrappers that save a few keystrokes, others address common tasks,
and others provide new functionality through suppr versions of existing
R functions. All are intended to be idiomatic R, as if they were
part of the base R packages.
Much of suppr is directly amended from the R source code - all credit
to the authors for their great work!
%''% or %""% - if the lhs is ““, return the rhs, else return the
lhs.%!||% - if the lhs is NULL, return the lhs, else return the rhs.%0% - if the lhs is of length 0, return the rhs, else return the
lhs.%allin%, %anyin%, %nonein%, %onein% and %notin% -
base::%in% variants."" %''% "a"
#> [1] "a"
NULL %!||% "a"
#> NULL
c() %0% "a"
#> [1] "a"
c("a", "b") %allin% c("a", "b", "c")
#> [1] TRUE
c("a", "d") %anyin% c("a", "b", "c")
#> [1] TRUE
c("a", "d") %nonein% c("a", "b", "c")
#> [1] FALSE
c("a", "d") %onein% c("a", "b", "c")
#> [1] TRUE
c("a", "d") %notin% c("a", "b", "c")
#> [1] FALSE TRUE
bckQuote() - backquotes a string.collapse() and collapse0() - collapse a vector (or vectors) into a
single string, optionally ‘recursively’ (in the sense of collapse each
argument individually and then collapse the results).listing() - turns a character vector into a human-readable list (in
the grammatical sense), optionally with quoting and/or a conjunction
like “and” or “or”.cat0() - base::cat() with sep = "".grepf(), grepi(), greplf(), grepli(), grepvf(), grepvi(),
subf(), subi(), gsubf() and gsubi() - strongly typed variants
of base::grep(), base::grepl(), base::grepv(), base::sub() and
base::gsub() for the common fixed = TRUE and ignore.case = TRUE
cases.anyZchar() - returns the 1-based index of the first zero character
element if any, otherwise 0.anyWS() - returns the 1-based index of the first all whitespace
element if any, otherwise 0. Optionally, zero character elements can
be treated as all whitespace.rm.prefix() and rm.suffix() - remove a specified prefix or suffix
from each element of a character vector.bckQuote(c("a", "b"))
#> [1] "`a`" "`b`"
collapse(c("a", "b", "c"))
#> [1] "abc"
listing(c("a", "b", "c"))
#> [1] "a, b and c."
cat0("a", "b", "c")
#> abc
greplf("foo", c("foo", "Foo", "bar"))
#> [1] TRUE FALSE FALSE
grepli("foo", c("foo", "Foo", "bar"))
#> [1] TRUE TRUE FALSE
anyZchar(c("hi", "bye", " ", ""))
#> [1] 4
anyWS(c("hi", "bye", " ", ""))
#> [1] 3
rm.prefix(c("x_apple", "x_banana"), "x_")
#> [1] "apple" "banana"
rm.suffix(c("apple_x", "banana_x"), "_x")
#> [1] "apple" "banana"
...) OperatorscheckDots() - version of base::chkDots() that can error, not just
warn.dotsNames() - returns the names of ... arguments, returning all
"" if unnamed (like methods::allNames() but without evaluating
...).subDots() - substitutes ... arguments, returning a list of the
substituted expressions.dp1Dots() - substitutes ... arguments, before applying
base::deparse1() to each, returning a character vector of the dot
arguments.f <- function(fn, ...) fn(...)
f(checkDots, a = 1, b = 2)
#> Error:
#> ! In f(checkDots, a = 1, b = 2) :
#> extra named arguments 'a', 'b' are not allowed.
f(dotsNames, 1, 2)
#> [1] "" ""
f(subDots, x = a + b, y = a * b)
#> $x
#> a + b
#>
#> $y
#> a * b
f(dp1Dots, x = a + b, y = a * b)
#> x y
#> "a + b" "a * b"
match.argv() - matches function argument input to a list of valid
values, not just strings like base::match.arg().stop2(), warning2() and stopifnot2() - wrappers for
base::stop(), base::warning() and base::stopifnot() that enable
the inclusion of any call on the stack in the error message via a more
flexible call. argument.warningifnot() - a wrapper for stopifnot2() that produces a
warning instead of an error.stopifnot.with() - a wrapper for stopifnot2() that evaluates
expressions in a specified environment/data object (like
base::with()).match.argv(1:3, list(c("a", "b"), list(1:3), 1:3))
#> [1] 1 2 3
f1 <- function(call.) stop2("error", call. = call.)
f2 <- function(call.) f1(call. = call.)
f2(call. = 2)
#> Error in `f2()`:
#> ! error
f1 <- function(call.) stopifnot2(all.equal(1, 2), call. = call.)
f2(call. = 1)
#> Error in `f1()`:
#> ! 1 and 2 are not equal:
#> Mean relative difference: 1
warningifnot(1 == 2, 3 > 4, warn.all = TRUE, call. = FALSE)
#> Warning: 1 == 2 is not TRUE
#> Warning: 3 > 4 is not TRUE
stopifnot.with(data.frame(x = 1, y = 2), x == y)
#> Error:
#> ! with data.frame(x = 1, y = 2) : x == y is not TRUE
addClass() - adds a class/classes to an object, either preserving
existing classes (by prepending given classes), or overwriting
existing classes, and returning the object.isVector() - wrapper for base::is.vector() that allows multiple
classes to be specified.is.Date(), is.datetype(), is.POSIXt(), is.POSIXct() and
is.POSIXlt() - date type predicates.is.boolean(), is.string() and nzstring() - predicates for common
scalar values.x <- structure(1:3, class = c("a", "b"))
class(addClass(x, "my_new_class"))
#> [1] "my_new_class" "a" "b"
isVector(1:3, c("character", "list", "numeric"))
#> [1] TRUE
is.Date(Sys.Date())
#> [1] TRUE
is.datetype(Sys.Date())
#> [1] TRUE
is.POSIXt(Sys.time())
#> [1] TRUE
is.POSIXct(Sys.time())
#> [1] TRUE
is.POSIXlt(Sys.time())
#> [1] FALSE
is.boolean(TRUE)
#> [1] TRUE
is.string("")
#> [1] TRUE
nzstring("")
#> [1] FALSE
is.even() and is.odd() - returns logical vector indicating if
elements are even or odd, respectively.is.even(c(-2:2, NA))
#> [1] TRUE FALSE TRUE FALSE TRUE FALSE
is.odd(c(1, 2, NA, Inf), noparity.na = TRUE)
#> [1] TRUE FALSE NA NA
whichMin() and whichMax() - wrappers for base::which.min() and
base::which.max() that offer a new loc argument to alternatively
return the first, last, or all, minima/maxima.x <- c(1, 2, 3, 1, 2, 3)
whichMin(x, loc = "first")
#> [1] 1
whichMin(x, loc = "last")
#> [1] 4
whichMin(x, loc = "all")
#> [1] 1 4
is.nonfinite() (and alias is.nf()) - returns a logical vector
indicating which elements are non-finite (i.e., NA, NaN, Inf or
-Inf).anyNF() - returns the 1-based index of the first non-finite value
if any, otherwise 0.whichNA() - returns the indices of NA values.setNA() - sets given indices to NA.na.vector() - returns a vector of NA values of a given length and
type.na.refill() - for an object that has had NA values removed by
stats::na.omit(), refill the NA values at the original indices,
returning an object of the same size as the original.is.nonfinite(c(1, 2, NA, Inf))
#> [1] FALSE FALSE TRUE TRUE
anyNF(c(1, 2, NA, Inf))
#> [1] 3
whichNA(c(1, 2, NA, Inf))
#> [1] 3
x <- c(1, 2, 3, 4)
setNA(x, c(1, 3))
#> [1] NA 2 NA 4
na.vector(5, type = "character")
#> [1] NA NA NA NA NA
x <- stats::na.omit(c(1, 2, NA, 4))
x
#> [1] 1 2 4
#> attr(,"na.action")
#> [1] 3
#> attr(,"class")
#> [1] "omit"
na.refill(x)
#> [1] 1 2 NA 4
#> attr(,"na.action")
#> [1] 3
#> attr(,"class")
#> [1] "refilled"
is.integerish() - returns TRUE if elements are all ‘integerish’ or
FALSE if not.is.whole() and is.wholenumber() - returns a single TRUE/FALSE,
or a logical vector, if elements are all whole numbers or not
(according to an input tolerance), respectively.is.integerish(c(1, 1.000000001))
#> [1] FALSE
is.whole(c(1, 1.000000001))
#> [1] TRUE
is.wholenumber(c(1, 2, 3.5, 4))
#> [1] TRUE TRUE FALSE TRUE
repeated() - returns a logical vector indicating which elements are
repeated (analogous to
duplicated(x, fromLast = FALSE) | duplicated(x, fromLast = TRUE)).whichRepeated() - returns the indices of repeated elements.repeats() (and alias non.unique()) - returns repeated elements.x <- c(1, 2, 3, 1, 2, 3, 4, 5)
repeated(x)
#> [1] TRUE TRUE TRUE TRUE TRUE TRUE FALSE FALSE
whichRepeated(x)
#> [1] 1 2 3 4 5 6
repeats(x)
#> [1] 1 2 3 1 2 3
rm.first() and rm.last() - removes the first or last ‘n’ elements
of a vector, respectively.x <- 1:10
rm.first(x, 3)
#> [1] 4 5 6 7 8 9 10
rm.last(x, 3)
#> [1] 1 2 3 4 5 6 7
predapply() - applies a predicate function to each element of a
vector, returning a logical vector. Option to reduce the output to a
single TRUE or FALSE value.empty.list() - wrapper for base::vector("list", length) that
returns an empty list of a given length.path() - wrapper for base::file.path() and
base::normalizePath(). Option to specify if the path is on a shared
drive, prepending .Platform$file.sep if so.dims() - returns the dimensions of an object, or c(length(x), 0L)
if it has no dim attribute.enumerate() - returns a list of lists - one for each element of a
vector, with the corresponding positional list containing the vector
element, index and name.libraries() and requires() - wrappers for base::library() and
base::require() that can load multiple packages at once, either from
names, strings, or character vectors.predapply(1:10, is.even, reduce = "any")
#> [1] TRUE
empty.list(2)
#> [[1]]
#> NULL
#>
#> [[2]]
#> NULL
path("mysd", "mydir", sharedDrive = TRUE, mustWork = FALSE)
#> [1] "\\\\mysd\\mydir"
dims(1:10)
#> [1] 10 0
enumerate(c("a", el = "b"))
#> [[1]]
#> [[1]]$idx
#> [1] 1
#>
#> [[1]]$val
#> [1] "a"
#>
#> [[1]]$name
#> [1] ""
#>
#>
#> [[2]]
#> [[2]]$idx
#> [1] 2
#>
#> [[2]]$val
#> [1] "b"
#>
#> [[2]]$name
#> [1] "el"
libraries(stats, "utils")
x <- c("stats", "utils")
requires(x, "methods", character.only = TRUE)
If you encounter a clear bug, please file an issue with a minimal reproducible example on GitHub.
Please note that the suppr project is released with a Contributor Code of Conduct. By contributing to this project, you agree to abide by its terms.