let
implements a mapping from desired names (names used directly in the expr code) to names used in the data.
Mnemonic: "expr code symbols are on the left, external data and function argument names are on the right."
let( alias, expr, ..., envir = parent.frame(), subsMethod = "langsubs", strict = TRUE, eval = TRUE, debugPrint = FALSE )
alias | mapping from free names in expr to target names to use (mapping have both unique names and unique values). |
---|---|
expr | block to prepare for execution. |
... | force later arguments to be bound by name. |
envir | environment to work in. |
subsMethod | character substitution method, one of 'langsubs' (preferred), 'subsubs', or 'stringsubs'. |
strict | logical if TRUE names and values must be valid un-quoted names, and not dot. |
eval | logical if TRUE execute the re-mapped expression (else return it). |
debugPrint | logical if TRUE print debugging information when in stringsubs mode. |
result of expr executed in calling environment (or expression if eval==FALSE).
Please see the wrapr
vignette
for some discussion of let and crossing function call boundaries: vignette('wrapr','wrapr')
.
For formal documentation please see https://github.com/WinVector/wrapr/blob/master/extras/wrapr_let.pdf.
Transformation is performed by substitution, so please be wary of unintended name collisions or aliasing.
Something like let
is only useful to get control of a function that is parameterized
(in the sense it take column names) but non-standard (in that it takes column names from
non-standard evaluation argument name capture, and not as simple variables or parameters). So wrapr:let
is not
useful for non-parameterized functions (functions that work only over values such as base::sum
),
and not useful for functions take parameters in straightforward way (such as base::merge
's "by
" argument).
dplyr::mutate
is an example where
we can use a let
helper. dplyr::mutate
is
parameterized (in the sense it can work over user supplied columns and expressions), but column names are captured through non-standard evaluation
(and it rapidly becomes unwieldy to use complex formulas with the standard evaluation equivalent dplyr::mutate_
).
alias
can not include the symbol ".
".
The intent from is from the user perspective to have (if
a <- 1; b <- 2
):
let(c(z = 'a'), z+b)
to behave a lot like
eval(substitute(z+b, c(z=quote(a))))
.
let
deliberately checks that it is mapping only to legal R
names;
this is to discourage the use of let
to make names to arbitrary values, as
that is the more properly left to R
's environment systems.
let
is intended to transform
"tame" variable and column names to "tame" variable and column names. Substitution
outcomes that are not valid simple R
variable names (produced with out use of
back-ticks) are forbidden. It is suggested that substitution targets be written
ALL_CAPS
style to make them stand out.
let
was inspired by gtools:strmacro()
.
Please see https://github.com/WinVector/wrapr/blob/master/extras/MacrosInR.md for a discussion of macro tools in R
.
d <- data.frame( Sepal_Length=c(5.8,5.7), Sepal_Width=c(4.0,4.4), Species='setosa') mapping <- qc( AREA_COL = Sepal_area, LENGTH_COL = Sepal_Length, WIDTH_COL = Sepal_Width ) # let-block notation let( mapping, d %.>% transform(., AREA_COL = LENGTH_COL * WIDTH_COL) )#> Sepal_Length Sepal_Width Species Sepal_area #> 1 5.8 4.0 setosa 23.20 #> 2 5.7 4.4 setosa 25.08# Note: in packages can make assignment such as: # AREA_COL <- LENGTH_COL <- WIDTH_COL <- NULL # prior to code so targets don't look like unbound names.