-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathREADME.Rmd
More file actions
251 lines (194 loc) · 9.58 KB
/
Copy pathREADME.Rmd
File metadata and controls
251 lines (194 loc) · 9.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
---
output: github_document
---
<!-- README.md is generated from README.Rmd. Please edit that file -->
```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "man/figures/README-",
out.width = "100%",
warning = FALSE,
message = FALSE
)
```
# suppr <img src="man/figures/logo.png" align="right" height="140" alt="" />
<!-- badges: start -->
[](https://github.com/LJ-Jenkins/suppr/actions/workflows/R-CMD-check.yaml)
<!-- badges: end -->
Supplementary utilities and extensions to `R` that are idiomatic in style.
## Installation
Install the latest release of suppr from CRAN:
```{r, eval = FALSE}
install.packages("suppr")
```
You can install the development version of suppr from GitHub:
```{r, eval = FALSE}
# install.packages("pak")
pak::pak("LJ-Jenkins/suppr")
```
## Reference
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!
#### Infix Operators
* `%''%` 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.
```{r, echo = FALSE}
library(suppr)
```
```{r}
"" %''% "a"
NULL %!||% "a"
c() %0% "a"
c("a", "b") %allin% c("a", "b", "c")
c("a", "d") %anyin% c("a", "b", "c")
c("a", "d") %nonein% c("a", "b", "c")
c("a", "d") %onein% c("a", "b", "c")
c("a", "d") %notin% c("a", "b", "c")
```
#### Character Operators
* `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.
```{r}
bckQuote(c("a", "b"))
collapse(c("a", "b", "c"))
listing(c("a", "b", "c"))
cat0("a", "b", "c")
greplf("foo", c("foo", "Foo", "bar"))
grepli("foo", c("foo", "Foo", "bar"))
anyZchar(c("hi", "bye", " ", ""))
anyWS(c("hi", "bye", " ", ""))
```
#### Dots (`...`) Operators
* `checkDots()` - 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.
```{r, error = TRUE}
f <- function(fn, ...) fn(...)
f(checkDots, a = 1, b = 2)
f(dotsNames, 1, 2)
f(subDots, x = a + b, y = a * b)
f(dp1Dots, x = a + b, y = a * b)
```
#### Messages, Warnings and Errors
* `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()`).
```{r, error = TRUE, warning = TRUE}
match.argv(1:3, list(c("a", "b"), list(1:3), 1:3))
f1 <- function(call.) stop2("error", call. = call.)
f2 <- function(call.) f1(call. = call.)
f2(call. = 2)
f1 <- function(call.) stopifnot2(all.equal(1, 2), call. = call.)
f2(call. = 1)
warningifnot(1 == 2, 3 > 4, warn.all = TRUE, call. = FALSE)
stopifnot.with(data.frame(x = 1, y = 2), x == y)
```
#### Classes
* `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.
```{r}
x <- structure(1:3, class = c("a", "b"))
class(addClass(x, "my_new_class"))
isVector(1:3, c("character", "list", "numeric"))
is.Date(Sys.Date())
is.datetype(Sys.Date())
is.POSIXt(Sys.time())
is.POSIXct(Sys.time())
is.POSIXlt(Sys.time())
is.boolean(TRUE)
is.string("")
nzstring("")
```
#### Data Wrangling
##### Even/odd
* `is.even()` and `is.odd()` - returns logical vector indicating if elements are even or odd, respectively.
```{r}
is.even(c(-2:2, NA))
is.odd(c(1, 2, NA, Inf), noparity.na = TRUE)
```
##### Which min/max
* `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.
```{r}
x <- c(1, 2, 3, 1, 2, 3)
whichMin(x, loc = "first")
whichMin(x, loc = "last")
whichMin(x, loc = "all")
```
##### NA's
* `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.
```{r}
is.nonfinite(c(1, 2, NA, Inf))
anyNF(c(1, 2, NA, Inf))
whichNA(c(1, 2, NA, Inf))
x <- c(1, 2, 3, 4)
setNA(x, c(1, 3))
na.vector(5, type = "character")
x <- stats::na.omit(c(1, 2, NA, 4))
x
na.refill(x)
```
##### Wholeness
* `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.
```{r}
is.integerish(c(1, 1.000000001))
is.whole(c(1, 1.000000001))
is.wholenumber(c(1, 2, 3.5, 4))
```
##### Duplicates
* `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()` - returns repeated elements.
```{r}
x <- c(1, 2, 3, 1, 2, 3, 4, 5)
repeated(x)
whichRepeated(x)
repeats(x)
```
##### Remove elements
* `rm.first()` and `rm.last()` - removes the first or last 'n' elements of a vector, respectively.
```{r}
x <- 1:10
rm.first(x, 3)
rm.last(x, 3)
```
#### Utilities
* `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.
```{r}
predapply(1:10, is.even, reduce = "any")
empty.list(2)
path("mysd", "mydir", sharedDrive = TRUE, mustWork = FALSE)
dims(1:10)
enumerate(c("a", el = "b"))
libraries(stats, "utils")
x <- c("stats", "utils")
requires(x, "methods", character.only = TRUE)
```
## Performance
Functions should have similar overhead to their nearest `R` equivalents. Most of the 'data wrangling' functions (and some others) have been implemented in `C` and typically perform equivalently to their `R` counterparts.
## Getting help
If you encounter a clear bug, please file an issue with a minimal reproducible example on [GitHub](https://github.com/LJ-Jenkins/suppr/issues).
## Code of Conduct
Please note that the suppr project is released with a [Contributor Code of Conduct](https://contributor-covenant.org/version/2/1/CODE_OF_CONDUCT.html). By contributing to this project, you agree to abide by its terms.