| which_first {hutilscpp} | R Documentation |
Where does a logical expression first return TRUE?
Description
A faster and safer version of which.max applied
to simple-to-parse logical expressions.
Usage
which_first(
expr,
verbose = FALSE,
reverse = FALSE,
sexpr,
eval_parent_n = 1L,
suppressWarning = getOption("hutilscpp_suppressWarning", FALSE),
use.which.max = FALSE
)
which_last(
expr,
verbose = FALSE,
reverse = FALSE,
suppressWarning = getOption("hutilscpp_suppressWarning", FALSE)
)
Arguments
expr |
An expression, such as |
verbose |
|
reverse |
|
sexpr |
Equivalent to |
eval_parent_n |
Passed to |
suppressWarning |
Either a |
use.which.max |
If |
Details
If the expr is of the form LHS <operator> RHS
and LHS is a single symbol, operator is one of
==, !=, >, >=, <, <=,
%in%,
or
%between%,
and RHS is numeric, then expr is not
evaluated directly; instead, each element of LHS is compared
individually.
If expr is not of the above form, then expr is evaluated
and passed to which.max.
Using this function can be significantly faster than the alternatives
when the computation
of expr would be expensive, though the difference is only likely to
be clear when length(x) is much larger than 10 million.
But even for smaller vectors, it has the benefit of returning
0L if none of the values in expr are TRUE, unlike
which.max.
Compared to Position for an appropriate
choice of f the speed of which_first is not much faster
when the expression is TRUE for some position. However, which_first
is faster when all elements of expr are FALSE.
Thus which_first has a smaller worst-case time than the
alternatives for most x.
Missing values on the RHS are handled specially.
which_first(x %between% c(NA, 1)) for example is equivalent to
which_first(x <= 1), as in data.table::between.
Value
The same as which.max(expr) or which(expr)[1] but returns 0L
when expr has no TRUE values.
Examples
N <- 1e5
# N <- 1e8 ## too slow for CRAN
# Two examples, from slowest to fastest,
# run with N = 1e8 elements
# seconds
x <- rep_len(runif(1e4, 0, 6), N)
bench_system_time(x > 5)
bench_system_time(which(x > 5)) # 0.8
bench_system_time(which.max(x > 5)) # 0.3
bench_system_time(which_first(x > 5)) # 0.000
## Worst case: have to check all N elements
x <- double(N)
bench_system_time(x > 0)
bench_system_time(which(x > 0)) # 1.0
bench_system_time(which.max(x > 0)) # 0.4 but returns 1, not 0
bench_system_time(which_first(x > 0)) # 0.1
x <- as.character(x)
# bench_system_time(which(x == 5)) # 2.2
bench_system_time(which.max(x == 5)) # 1.6
bench_system_time(which_first(x == 5)) # 1.3