Skip to content

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_arg = NULL,
  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 with names() 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 if expr attempts to select or rename a variable that doesn't exist. If FALSE, 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 like c(foo = c(bar = starts_with("foo"))). See the name_spec argument of vctrs::vec_c() for a description of valid name specs.

allow_rename

If TRUE (the default), the renaming syntax c(foo = bar) is allowed. If FALSE, it causes an error. This is useful to implement purely selective behaviour.

allow_empty

If TRUE (the default), it is ok for expr to result in an empty selection. If FALSE, will error if expr yields an empty selection.

allow_predicates

If TRUE (the default), it is ok for expr to use predicates (i.e. in where()). If FALSE, will error if expr uses a predicate. Will automatically be set to FALSE if data does not support predicates (as determined by tidyselect_data_has_predicates()).

before_arg, after_arg

Argument names for before and after. These are used in error messages.

env

The environment in which to evaluate expr. Discarded if expr is a quosure.

error_arg

Argument names for expr. These are used in error messages. (You can use "..." if expr = c(...)).

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 the call argument of abort() 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