If you wish to write a function that uses a programmable NSE function and
forwards its NSE arguments to it, you must ensure the NSE expressions are
evaluated in the correct environment, typically the parent.frame(). This is
no different than with normal NSE functions. An example:
subset3 <- function(x, subset, select, drop=FALSE) { frm <- parent.frame() # as per note in ?parent.frame, better to call here sub.q <- expand(substitute(subset), x, frm) sel.q <- expand(substitute(select), x, frm) eval(bquote(base::subset(.(x), .(sub.q), .(sel.q), drop=.(drop))), frm) }
We use bquote to assemble our substituted call and eval to evaluate it in
the correct frame. The parts of the call that should evaluate in subset3 are
escaped with .(). This requires some work from the programmer, but the user
reaps the benefits:
col <- quote(Sepal.Length) sub <- quote(Species == 'setosa') subset3(iris, sub & col > 5.5, col:Petal.Length)
Notice that we used expand with the base NSE function subset. Because
expand just generates language objects, you can use it with any NSE function.
The forwarding is robust to unusual evaluation:
col.a <- quote(I_dont_exist) col.b <- quote(Sepal.Length) sub.a <- quote(stop("all hell broke loose")) threshold <- 3.35 local({ col.a <- quote(Sepal.Width) sub.a <- quote(Species == 'virginica') subs <- list(sub.a, quote(Species == 'versicolor')) lapply( subs, function(x) subset3(iris, x & col.a > threshold, col.b:Petal.Length) ) })
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.