```
library(rlang)
# Interpret defused code as selection:
x <- expr(mpg:cyl)
eval_select(x, mtcars)
# Interpret defused code as a renaming selection. All inputs must
# be named within `c()`:
try(eval_rename(expr(mpg), mtcars))
eval_rename(expr(c(foo = mpg)), mtcars)
# Within a function, use `enquo()` to defuse one argument:
my_function <- function(x, expr) {
eval_select(enquo(expr), x)
}
# If your function takes dots, evaluate a defused call to `c(...)`
# with `expr(c(...))`:
my_function <- function(.x, ...) {
eval_select(expr(c(...)), .x)
}
# If your function takes dots and a named argument, use `{{ }}`
# inside the defused expression to tunnel it inside the tidyselect DSL:
my_function <- function(.x, .expr, ...) {
eval_select(expr(c({{ .expr }}, ...)), .x)
}
# Note that the trick above works because `expr({{ arg }})` is the
# same as `enquo(arg)`.
# The evaluators return a named vector of locations. Here are
# examples of using these location vectors to implement `select()`
# and `rename()`:
select <- function(.x, ...) {
pos <- eval_select(expr(c(...)), .x)
set_names(.x[pos], names(pos))
}
rename <- function(.x, ...) {
pos <- eval_rename(expr(c(...)), .x)
names(.x)[pos] <- names(pos)
.x
}
select(mtcars, mpg:cyl)
rename(mtcars, foo = mpg)
```

Run the code above in your browser using DataLab