--- title: "eply" author: "William Michael Landau" date: "`r Sys.Date()`" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{eply} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- The `eply` package processes batches of quoted expressions. Just as `apply()` acts on data frames of function arguments, `eply()` acts on data frames of quoted **expressions** that **return** arguments. The package also has `evals()`, which simply evaluates a character vector of quoted expressions, plus some nice utilities. # Function `eply()` ```{r} library(eply) ``` `eply()` applies a function over a data frame of quoted expressions. Begin with a function. ```{r} .fun = example.fun .fun ``` Then, make a data frame of quoted expressions that return arguments to `.fun`. ```{r} .expr = example.expr() .expr # str(.expr) # The expressions are actually just characters. ``` Define the variables referenced in `.expr`. ```{r} a = 1 b = 2 ``` For each row in `.expr`, `eply()` evaluates the expressions and feeds the results to `.fun`. ```{r} eply(.fun, .expr) ``` # Function `evals()` `evals()` evaluates a character vector of quoted expressions. ```{r} evals(c("1+1", "2+2", "3+3")) evals(c("1+1", "2+2", "3+3"), .simplify = FALSE) a = 4 evals(c("subset(mtcars, cyl == a, mpg, TRUE)", "mtcars[1:2, 1:2]")) ``` # Control the evaluation environment Use the `.with` argument to control the environment in which the expressions are evaluated. `.with` can be a list, data frame, or environment. Data in the calling environment may be used as well, so take care to avoid ambiguities. ```{r} .fun = function(x) return(x) .expr = data.frame(x = c("1+a", "1+b")) rownames(.expr) = c("expr1", "expr2") a = b = 0 .with = list(a = 1, b = 2) eply(.fun, .expr, .with) evals(.expr$x, .with) ``` The `.with` argument is especially important if you wish to pass `eply()` or `evals()` to an iteration function like `lapply()`. ```{r} .expr2 = split(.expr, f = .expr$x) # list of rows of .expr lapply(.expr2, eply, .fun = .fun, .with = .with) lapply(c("1+X", "2+Y"), evals, .with = list(X = 1, Y = 2)) ``` # Parallel execution Eply does not implement any special parallel computing functionality. However, the `parallel` package may be used on non-Windows machines to distribute subsets of `.expr` across parallel processes. The output of `parallel::mclapply()` is a list, so take care to simplify if necessary (say, to a data frame). ```{r, eval = F} library(parallel) .fun = example.fun expr.dataframe = example.expr() expr.list = split(expr.dataframe, f = expr.dataframe$rep) # split expr.dataframe by rep .with = example.with() mclapply(X = expr.list, FUN = eply, .fun = .fun, .with = .with, mc.cores = 2) ``` The parallel execution of `evals()` with `mclapply()` is similar. For an alternative, consider the [`plyr`](http://seananderson.ca/2013/12/01/plyr.html) package to parallelize `eply()` over chunks of `.expr`. See the ["Parallel processing"](http://seananderson.ca/2013/12/01/plyr.html#parallel-processing) section of the linked guide. # Character vector manipulation If you want some quoted expressions to evaluate to character strings, enclosed them with literal escaped quotes. ```{r} .expr = data.frame( string = quotes(c("a", "b")), variable = c("c", "d")) .expr .fun = function(string, variable) paste(string, variable) .with = list(c = "C", d = "D") eply(.fun, .expr, .with) ``` You can use single or double quotes. ```{r} quotes(c("x", "y")) quotes(c("x", "y"), single = FALSE) quotes(c("x", "y"), single = TRUE) ``` Undo with `unquote()`. ```{r} .expr$string = unquote(.expr$string) .expr x = quotes(quotes(c("x", "y"), single = TRUE)) x unquote(x, deep = TRUE) unquote(x, deep = FALSE) ``` Turn valid expressions into strings with `strings()`. ```{r} data.frame( arg1 = strings(a + b, sqrt(x) - 2), arg2 = 1:2) ``` # More help ```{r} help_eply() ```