eval_tidy | R Documentation |
eval_tidy()
is a variant of base::eval()
that powers the tidy
evaluation framework. Like eval()
it accepts user data as
argument. Whereas eval()
simply transforms the data to an
environment, eval_tidy()
transforms it to a data mask with as_data_mask()
. Evaluating in a data
mask enables the following features:
Quosures. Quosures are expressions bundled with
an environment. If data
is supplied, objects in the data mask
always have precedence over the quosure environment, i.e. the
data masks the environment.
Pronouns. If data
is supplied, the .env
and .data
pronouns are installed in the data mask. .env
is a reference to
the calling environment and .data
refers to the data
argument. These pronouns are an escape hatch for the data mask ambiguity problem.
eval_tidy(expr, data = NULL, env = caller_env())
expr |
An expression or quosure to evaluate. |
data |
A data frame, or named list or vector. Alternatively, a
data mask created with |
env |
The environment in which to evaluate |
base::eval()
is sufficient for simple evaluation. Use
eval_tidy()
when you'd like to support expressions referring to
the .data
pronoun, or when you need to support quosures.
If you're evaluating an expression captured with
injection support, it is recommended to use
eval_tidy()
because users may inject quosures.
Note that unwrapping a quosure with quo_get_expr()
does not
guarantee that there is no quosures inside the expression. Quosures
might be unquoted anywhere in the expression tree. For instance,
the following does not work reliably in the presence of nested
quosures:
my_quoting_fn <- function(x) { x <- enquo(x) expr <- quo_get_expr(x) env <- quo_get_env(x) eval(expr, env) } # Works: my_quoting_fn(toupper(letters)) # Fails because of a nested quosure: my_quoting_fn(toupper(!!quo(letters)))
eval_tidy()
eval_tidy()
always evaluates in a data mask, even when data
is
NULL
. Because of this, it has different stack semantics than
base::eval()
:
Lexical side effects, such as assignment with <-
, occur in the
mask rather than env
.
Functions that require the evaluation environment to correspond
to a frame on the call stack do not work. This is why return()
called from a quosure does not work.
The mask environment creates a new branch in the tree
representation of backtraces (which you can visualise in a
browser()
session with lobstr::cst()
).
See also eval_bare()
for more information about these differences.
What is data-masking and why do I need {{?.
What are quosures and when are they needed?.
Defusing R expressions.
new_data_mask()
and as_data_mask()
for manually creating data masks.
# With simple defused expressions eval_tidy() works the same way as
# eval():
fruit <- "apple"
vegetable <- "potato"
expr <- quote(paste(fruit, vegetable, sep = " or "))
expr
eval(expr)
eval_tidy(expr)
# Both accept a data mask as argument:
data <- list(fruit = "banana", vegetable = "carrot")
eval(expr, data)
eval_tidy(expr, data)
# The main difference is that eval_tidy() supports quosures:
with_data <- function(data, expr) {
quo <- enquo(expr)
eval_tidy(quo, data)
}
with_data(NULL, fruit)
with_data(data, fruit)
# eval_tidy() installs the `.data` and `.env` pronouns to allow
# users to be explicit about variable references:
with_data(data, .data$fruit)
with_data(data, .env$fruit)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.