eval_relocate()
is a variant of eval_select()
that moves a selection to
a new location. Either before
or after
can be provided to specify where
to move the selection to. This powers dplyr::relocate()
.
Usage
eval_relocate(
expr,
data,
...,
before = NULL,
after = NULL,
strict = TRUE,
name_spec = NULL,
allow_rename = TRUE,
allow_empty = TRUE,
allow_predicates = TRUE,
before_arg = "before",
after_arg = "after",
env = caller_env(),
error_call = caller_env()
)
Arguments
- expr
Defused R code describing a selection according to the tidyselect syntax.
- data
A named list, data frame, or atomic vector. Technically,
data
can be any vector withnames()
and"[["
implementations.- ...
These dots are for future extensions and must be empty.
- before, after
Defused R code describing a selection according to the tidyselect syntax. The selection represents the destination of the selection provided through
expr
. Supplying neither of these will move the selection to the left-hand side. Supplying both of these is an error.- strict
If
TRUE
, out-of-bounds errors are thrown ifexpr
attempts to select or rename a variable that doesn't exist. IfFALSE
, failed selections or renamings are ignored.- name_spec
A name specification describing how to combine or propagate names. This is used only in case nested
c()
expressions likec(foo = c(bar = starts_with("foo")))
. See thename_spec
argument ofvctrs::vec_c()
for a description of valid name specs.- allow_rename
If
TRUE
(the default), the renaming syntaxc(foo = bar)
is allowed. IfFALSE
, it causes an error. This is useful to implement purely selective behaviour.- allow_empty
If
TRUE
(the default), it is ok forexpr
to result in an empty selection. IfFALSE
, will error ifexpr
yields an empty selection.- allow_predicates
If
TRUE
(the default), it is ok forexpr
to use predicates (i.e. inwhere()
). IfFALSE
, will error ifexpr
uses a predicate. Will automatically be set toFALSE
ifdata
does not support predicates (as determined bytidyselect_data_has_predicates()
).- before_arg, after_arg
Argument names for
before
andafter
. These are used in error messages.- env
The environment in which to evaluate
expr
. Discarded ifexpr
is a quosure.- error_call
The execution environment of a currently running function, e.g.
caller_env()
. The function will be mentioned in error messages as the source of the error. See thecall
argument ofabort()
for more information.
Value
A named vector of numeric locations with length equal to length(data)
.
Each position in data
will be represented exactly once.
The names are normally the same as in the input data, except when the user
supplied named selections with c()
. In the latter case, the names reflect
the new names chosen by the user.
Examples
library(rlang)
# Interpret defused code as a request to relocate
x <- expr(c(mpg, disp))
after <- expr(wt)
eval_relocate(x, mtcars, after = after)
#> cyl hp drat wt mpg disp qsec vs am gear carb
#> 2 4 5 6 1 3 7 8 9 10 11
# Supplying neither `before` nor `after` will move the selection to the
# left-hand side
eval_relocate(x, mtcars)
#> mpg disp cyl hp drat wt qsec vs am gear carb
#> 1 3 2 4 5 6 7 8 9 10 11
# Within a function, use `enquo()` to defuse a single argument.
# Note that `before` and `after` must also be defused with `enquo()`.
my_relocator <- function(x, expr, before = NULL, after = NULL) {
eval_relocate(enquo(expr), x, before = enquo(before), after = enquo(after))
}
my_relocator(mtcars, vs, before = hp)
#> mpg cyl disp vs hp drat wt qsec am gear carb
#> 1 2 3 8 4 5 6 7 9 10 11
# Here is an example of using `eval_relocate()` to implement `relocate()`.
# Note that the dots are passed on as a defused call to `c(...)`.
relocate <- function(.x, ..., .before = NULL, .after = NULL) {
pos <- eval_relocate(
expr(c(...)),
.x,
before = enquo(.before),
after = enquo(.after)
)
set_names(.x[pos], names(pos))
}
relocate(mtcars, vs, .before = hp)
#> mpg cyl disp vs hp drat wt qsec am gear carb
#> Mazda RX4 21.0 6 160.0 0 110 3.90 2.620 16.46 1 4 4
#> Mazda RX4 Wag 21.0 6 160.0 0 110 3.90 2.875 17.02 1 4 4
#> Datsun 710 22.8 4 108.0 1 93 3.85 2.320 18.61 1 4 1
#> Hornet 4 Drive 21.4 6 258.0 1 110 3.08 3.215 19.44 0 3 1
#> Hornet Sportabout 18.7 8 360.0 0 175 3.15 3.440 17.02 0 3 2
#> Valiant 18.1 6 225.0 1 105 2.76 3.460 20.22 0 3 1
#> Duster 360 14.3 8 360.0 0 245 3.21 3.570 15.84 0 3 4
#> Merc 240D 24.4 4 146.7 1 62 3.69 3.190 20.00 0 4 2
#> Merc 230 22.8 4 140.8 1 95 3.92 3.150 22.90 0 4 2
#> Merc 280 19.2 6 167.6 1 123 3.92 3.440 18.30 0 4 4
#> Merc 280C 17.8 6 167.6 1 123 3.92 3.440 18.90 0 4 4
#> Merc 450SE 16.4 8 275.8 0 180 3.07 4.070 17.40 0 3 3
#> Merc 450SL 17.3 8 275.8 0 180 3.07 3.730 17.60 0 3 3
#> Merc 450SLC 15.2 8 275.8 0 180 3.07 3.780 18.00 0 3 3
#> Cadillac Fleetwood 10.4 8 472.0 0 205 2.93 5.250 17.98 0 3 4
#> Lincoln Continental 10.4 8 460.0 0 215 3.00 5.424 17.82 0 3 4
#> Chrysler Imperial 14.7 8 440.0 0 230 3.23 5.345 17.42 0 3 4
#> Fiat 128 32.4 4 78.7 1 66 4.08 2.200 19.47 1 4 1
#> Honda Civic 30.4 4 75.7 1 52 4.93 1.615 18.52 1 4 2
#> Toyota Corolla 33.9 4 71.1 1 65 4.22 1.835 19.90 1 4 1
#> Toyota Corona 21.5 4 120.1 1 97 3.70 2.465 20.01 0 3 1
#> Dodge Challenger 15.5 8 318.0 0 150 2.76 3.520 16.87 0 3 2
#> AMC Javelin 15.2 8 304.0 0 150 3.15 3.435 17.30 0 3 2
#> Camaro Z28 13.3 8 350.0 0 245 3.73 3.840 15.41 0 3 4
#> Pontiac Firebird 19.2 8 400.0 0 175 3.08 3.845 17.05 0 3 2
#> Fiat X1-9 27.3 4 79.0 1 66 4.08 1.935 18.90 1 4 1
#> Porsche 914-2 26.0 4 120.3 0 91 4.43 2.140 16.70 1 5 2
#> Lotus Europa 30.4 4 95.1 1 113 3.77 1.513 16.90 1 5 2
#> Ford Pantera L 15.8 8 351.0 0 264 4.22 3.170 14.50 1 5 4
#> Ferrari Dino 19.7 6 145.0 0 175 3.62 2.770 15.50 1 5 6
#> Maserati Bora 15.0 8 301.0 0 335 3.54 3.570 14.60 1 5 8
#> Volvo 142E 21.4 4 121.0 1 109 4.11 2.780 18.60 1 4 2
relocate(mtcars, starts_with("d"), .after = last_col())
#> mpg cyl hp wt qsec vs am gear carb disp drat
#> Mazda RX4 21.0 6 110 2.620 16.46 0 1 4 4 160.0 3.90
#> Mazda RX4 Wag 21.0 6 110 2.875 17.02 0 1 4 4 160.0 3.90
#> Datsun 710 22.8 4 93 2.320 18.61 1 1 4 1 108.0 3.85
#> Hornet 4 Drive 21.4 6 110 3.215 19.44 1 0 3 1 258.0 3.08
#> Hornet Sportabout 18.7 8 175 3.440 17.02 0 0 3 2 360.0 3.15
#> Valiant 18.1 6 105 3.460 20.22 1 0 3 1 225.0 2.76
#> Duster 360 14.3 8 245 3.570 15.84 0 0 3 4 360.0 3.21
#> Merc 240D 24.4 4 62 3.190 20.00 1 0 4 2 146.7 3.69
#> Merc 230 22.8 4 95 3.150 22.90 1 0 4 2 140.8 3.92
#> Merc 280 19.2 6 123 3.440 18.30 1 0 4 4 167.6 3.92
#> Merc 280C 17.8 6 123 3.440 18.90 1 0 4 4 167.6 3.92
#> Merc 450SE 16.4 8 180 4.070 17.40 0 0 3 3 275.8 3.07
#> Merc 450SL 17.3 8 180 3.730 17.60 0 0 3 3 275.8 3.07
#> Merc 450SLC 15.2 8 180 3.780 18.00 0 0 3 3 275.8 3.07
#> Cadillac Fleetwood 10.4 8 205 5.250 17.98 0 0 3 4 472.0 2.93
#> Lincoln Continental 10.4 8 215 5.424 17.82 0 0 3 4 460.0 3.00
#> Chrysler Imperial 14.7 8 230 5.345 17.42 0 0 3 4 440.0 3.23
#> Fiat 128 32.4 4 66 2.200 19.47 1 1 4 1 78.7 4.08
#> Honda Civic 30.4 4 52 1.615 18.52 1 1 4 2 75.7 4.93
#> Toyota Corolla 33.9 4 65 1.835 19.90 1 1 4 1 71.1 4.22
#> Toyota Corona 21.5 4 97 2.465 20.01 1 0 3 1 120.1 3.70
#> Dodge Challenger 15.5 8 150 3.520 16.87 0 0 3 2 318.0 2.76
#> AMC Javelin 15.2 8 150 3.435 17.30 0 0 3 2 304.0 3.15
#> Camaro Z28 13.3 8 245 3.840 15.41 0 0 3 4 350.0 3.73
#> Pontiac Firebird 19.2 8 175 3.845 17.05 0 0 3 2 400.0 3.08
#> Fiat X1-9 27.3 4 66 1.935 18.90 1 1 4 1 79.0 4.08
#> Porsche 914-2 26.0 4 91 2.140 16.70 0 1 5 2 120.3 4.43
#> Lotus Europa 30.4 4 113 1.513 16.90 1 1 5 2 95.1 3.77
#> Ford Pantera L 15.8 8 264 3.170 14.50 0 1 5 4 351.0 4.22
#> Ferrari Dino 19.7 6 175 2.770 15.50 0 1 5 6 145.0 3.62
#> Maserati Bora 15.0 8 335 3.570 14.60 0 1 5 8 301.0 3.54
#> Volvo 142E 21.4 4 109 2.780 18.60 1 1 4 2 121.0 4.11