knitr::opts_chunk$set(error=TRUE, comment=NA) library(oshka)
One drawback of the eval
/bquote
/.()
pattern is that the actual objects
inside .()
are placed on the call stack. This is not an issue with symbols,
but can be bothersome with data or functions. For example, in:
my_fun_inner <- function(x) { # ... bunch of code stop("end") } my_fun_outer <- function(x) { eval(bquote(.(my_fun)(.(x))), parent.frame()) } my_fun_outer(mtcars) traceback()
The entire deparsed function definition and data frame will be displayed in the traceback, which makes it difficult to see what is happening. A simple work-around is to use:
sapply(.traceback(), head, 1) sapply(sys.calls(), head, 1) # sys.calls is similarly affected
rlang
oshka
is simple in design and purpose. It exports a single function that
substitutes expressions into other expressions. It hews closely to R semantics.
rlang
is more ambitious and more complex as a result. To use it you must
learn new concepts and semantics.
One manifestation of the additional complexity in rlang
is that you must
unquote expressions to use them:
rlang.b <- quo(Species == 'virginica') rlang.c <- quo(Sepal.Width > 3.6) rlang.d <- quo(!!rlang.b & !!rlang.c) dplyr::filter(iris, !!rlang.d)
As shown earlier, the expand
version is more straightforward as it uses the
standard quote
function and does not require unquoting:
On the other hand, forwarding of NSE arguments to NSE functions is simpler
in rlang
due to environment capture feature of quosures:
rlang_virginica <- function(subset) { subset <- enquo(subset) dplyr::filter(iris, Species == 'virginica' & !!subset) }
Because oshka
does not capture environments, we must resort to the
eval
/bquote
pattern:
oshka_virginica <- function(subset) { subset <- bquote(Species == 'virginica' & .(substitute(subset))) eval(bquote(.(subset2)(iris, .(subset))), parent.frame()) }
oshka
minimizes the complexity in what we see as the most common use
case, and sticks to R semantics for the more complicated ones.
For additional discussion on rlang
see the following presentations:
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.