An alternative approach to non-standard evaluation using formulas. Provides a full implementation of LISP style 'quasiquotation', making it easier to generate code with other code.
The lazyeval package provides tools that make it easier to correctly implement non-standard evaluation (NSE) in R. You use lazy evaluation by requiring the user to "quote" specially evaluated arguments with
~, and then using the lazyeval package to compute with those formulas. It is also possible to eliminate the use of the
~ by converting promises to formulas. This does make programming with such functions a little harder, but it can be worth it in certain situations. See
vignette("lazyeval") for more details.
Install the released version from CRAN with:
Install the development version from github with:
# install.packages("devtools")devtools::install_github("hadley/lazyeval", build_vignettes = TRUE)
Lazyeval has a new system for lazy-eval based on formulas, described in depth in the new
lazyeval vignette. This system is still a little experimental - it hasn't seen much use outside of the vignette, so it certainly may change a little in the future. However, long-term goal is to use these tools across all of my packages (ggplot2, tidyr, dplyr, etc), and I am fairly confident that this is a robust system that won't need major changes.
There are three key components:
f_eval() evaluates a formula in the environment where it was defined.
If supplied, values are first looked for in an optional
.env can be used to resolve ambiguity in this case.
(#43). Longer forms
f_eval_lhs() emphasise the side
of the formula that you want to evaluate (#64).
f_interp() provides a full quasiquoting system using
uq() for unquote
uqs() for unquote-splice (#36).
dots_capture() make it easy to turn promises
... into explicit formulas. These should be used sparingly, as
generally lazy-eval is preferred to non-standard eval.
For functions that work with
as_f_list() make it
possible to use the evaluated LHS of a formula to name the elements of a
The core components are accompanied by a number of helper functions:
Identify a formula with
Create a formula from a quoted call and an environment with
"Unwrap" a formula removing one level from the stack of parent environments
Get or set either side of a formula with
the environment with
Convert to text/label with
I've also added
expr_label() explicitly to find the expression associated with a function argument, and label it for output (#58). This is one of the primary uses cases for NSE.
expr_env() is a similar helper that returns the environment associated with a promise (#67).
.ignore_empty argument to drop extra arguments (#32).
interp.formula() only accepts single-sided formulas (#37).
interp() accepts an environment in
interp.character() always produes a single string, regardless of
input length (#27).
Fixed an infinite loop in
lazy_dots(.follow_symbols = TRUE) (#22, #24)
lazy() now fails with an informative error when it is applied on
an object that has already been evaluated (#23, @lionel-).
lazy() no longer follows the expressions of lazily loaded objects
as.lazy_dots() gains a method for NULL, returning a zero-length
auto_names() no longer truncates symbols (#19, #20)