Skip to content

Commit a2ffc48

Browse files
Nj221102nitish jhatdhockMichaelChiricojangorecki
authored
Document passing fun to env arg
Co-authored-by: nitish jha <[email protected]> Co-authored-by: Toby Dylan Hocking <[email protected]> Co-authored-by: Michael Chirico <[email protected]> Co-authored-by: Michael Chirico <[email protected]> Co-authored-by: Jan Gorecki <[email protected]>
1 parent 885f7c7 commit a2ffc48

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

man/data.table.Rd

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,10 @@ DT[, list(MySum=sum(v),
422422
MyMax=max(v)),
423423
by=.(x, y\%\%2)] # by 2 expressions
424424

425+
# programmatic query with env=
426+
DT[, .(funvar = fun(var)), by=grp_var,
427+
env = list(fun="sum", var="a", funvar="sum_a_by_x", grp_var="x")]
428+
425429
DT[, .(a = .(a), b = .(b)), by=x] # list columns
426430
DT[, .(seq = min(a):max(b)), by=x] # j is not limited to just aggregations
427431
DT[, sum(v), by=x][V1<20] # compound query

vignettes/datatable-programming.Rmd

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,33 @@ DT[filter_col %in% filter_val,
204204
)]
205205
```
206206

207+
### Substitute functions
208+
209+
A tiny clarification may be useful on how we can substitute a function name in an expression.
210+
Note that providing `outer="sqrt"` (string) vs. `outer=sqrt` (symbol) is very different:
211+
```{r substitute_fun1, result='hide'}
212+
DT[, outer(Sepal.Length), env = list(outer="sqrt"), verbose=TRUE]
213+
#Argument 'j' after substitute: sqrt(Sepal.Length)
214+
## DT[, sqrt(Sepal.Length)]
215+
216+
DT[, outer(Sepal.Length), env = list(outer=sqrt), verbose=TRUE]
217+
#Argument 'j' after substitute: .Primitive("sqrt")(Sepal.Length)
218+
## DT[, .Primitive("sqrt")(Sepal.Length)]
219+
```
220+
And while `.Primitive("sqrt")(Sepal.Length)` still works, it is almost never the desired form.
221+
222+
Even more importantly, if the symbol form is meant to be used, then it can, and should, be used directly in the expression, as there is no need for substitution.
223+
```{r substitute_fun2, result='hide'}
224+
DT[, sqrt(Sepal.Length)]
225+
```
226+
227+
If function name to be substituted needs to be namespace-qualified then namespace and function name can be substituted as any other symbol in the expression:
228+
```{r substitute_fun3, result='hide'}
229+
DT[, ns::fun(Sepal.Length), env = list(ns="base", fun="sqrt"), verbose=TRUE]
230+
#Argument 'j' after substitute: base::sqrt(Sepal.Length)
231+
## DT[, base::sqrt(Sepal.Length)]
232+
```
233+
207234
### Substitute variables and character values
208235

209236
In the above example, we have seen a convenient feature of `substitute2`: automatic conversion from strings into names/symbols. An obvious question arises: what if we actually want to substitute a parameter with a *character* value, so as to have base R `substitute` behaviour. We provide a mechanism to escape automatic conversion by wrapping the elements into base R `I()` call. The `I` function marks an object as *AsIs*, preventing its arguments from character-to-symbol automatic conversion. (Read the `?AsIs` documentation for more details.) If base R behaviour is desired for the whole `env` argument, then it's best to wrap the whole argument in `I()`. Alternatively, each list element can be wrapped in `I()` individually. Let's explore both cases below.

0 commit comments

Comments
 (0)