r-lib / rlang

Low-level API for programming with R
https://rlang.r-lib.org
Other
508 stars 138 forks source link

Offer a shortcut for eval_tidy(enquo(x))? #812

Closed krlmlr closed 3 years ago

krlmlr commented 5 years ago

For new users test-driving tidy evaluation (e.g. the {{}} mustaches), it would help to have a shortcut that operates like a quoting function. What would be a good name for eval_tidy_quo()?

library(rlang)

eval_tidy_quo <- function(expr, data = NULL, env = caller_env()) {
  eval_tidy(enquo(expr), data = data, env = env)
}

b <- 5
a <- sym("b")

# This is not tidy evaluation, a is unquoted eagerly?
eval_tidy({{a}})
#> [1] 5
eval_tidy(a)
#> [1] 5
eval_tidy({{a}}, data = list(b = 3))
#> [1] 3
eval_tidy(a, data = list(b = 3))
#> [1] 3

# Tidy evaluation without mustache:
eval_tidy_quo(a)
#> b

# Not picking up b from .GlobalEnv here
try(eval_tidy_quo({{a}}))
#> Error in eval_tidy(enquo(expr), data = data, env = env) : 
#>   object 'b' not found

# ...but works with the data mask
eval_tidy_quo({{a}}, data = list(b = 3))
#> [1] 3

# A quosure works
a <- quo(b)
eval_tidy_quo({{a}})
#> [1] 5

# Mustaches implement quote-unquote in a function:
quoting_fun <- function(expr) {
  eval_tidy_quo({{expr}})
}

quoting_fun(a)
#> <quosure>
#> expr: ^b
#> env:  global
quoting_fun({{a}})
#> [1] 5

Created on 2019-07-17 by the reprex package (v0.3.0)

lionel- commented 5 years ago

This is with_data() ;)

krlmlr commented 5 years ago

It looks like this function only lives in the examples?

Would it be too bad to introduce quo_eval() and expr_eval() as safer and less ambiguous alternatives to eval_tidy()? We still need to think of a name that also works in situations when we test-drive tidy evaluation without a data mask.

Forgot to mention the motivation for this question: https://community.rstudio.com/t/how-to-pass-optional-quosures-to-a-tibble/34371/9. CC @courtiol.

lionel- commented 5 years ago

I think we need expand() as eval + enexpr and with_data() as eval_tidy + enquo.

krlmlr commented 5 years ago

expand() is already a tidyr verb. IMO, with_data(data = NULL) looks weird.

lionel- commented 5 years ago

It's not necessarily a concern for rlang that expand() is a tidyverse verb.

I think it looks fine:

mtcars %>% with_data(cyl + am)
krlmlr commented 5 years ago

Also discussed in #591.

lionel- commented 4 years ago

Useful case for with_data(): https://stackoverflow.com/questions/61229332/function-to-run-over-selected-columns-with-dplyr-tidyeval/61230024#61230024

lionel- commented 3 years ago

Let's keep thinking about this.