enquo()
and enquos()
defuse function arguments.
A defused expression can be examined, modified, and injected into
other expressions.
Defusing function arguments is useful for:
Creating data-masking functions.
Interfacing with another data-masking function using the defuse-and-inject pattern.
These are advanced tools. Make sure to first learn about the embrace
operator {{
in Data mask programming patterns.
{{
is easier to work with with less theory, and it is sufficient
in most applications.
An unquoted argument name. The expression supplied to that argument is defused and returned.
Names of arguments to defuse.
If TRUE
, unnamed inputs are automatically named
with as_label()
. This is equivalent to applying
exprs_auto_name()
on the result. If FALSE
, unnamed elements
are left as is and, if fully unnamed, the list is given minimal
names (a vector of ""
). If NULL
, fully unnamed results are
left with NULL
names.
Whether to ignore empty arguments. Can be one
of "trailing"
, "none"
, "all"
. If "trailing"
, only the
last argument is ignored if it is empty. Named arguments are not
considered empty.
Whether to treat :=
as =
. Unlike =
, the
:=
syntax supports names injection.
How to treat arguments with the same name. The
default, "keep"
, preserves these arguments. Set .homonyms
to
"first"
to only keep the first occurrences, to "last"
to keep
the last occurrences, and to "error"
to raise an informative
error and indicate what arguments have duplicated names.
Whether to check for <-
calls. When TRUE
a
warning recommends users to use =
if they meant to match a
function parameter or wrap the <-
call in curly braces otherwise.
This ensures assignments are explicit.
enquo()
returns a quosure and enquos()
returns a list of quosures.
Arguments defused with enquo()
and enquos()
automatically gain
injection support.
my_mean <- function(data, var) {
var <- enquo(var)
dplyr::summarise(data, mean(!!var))
}
# Can now use `!!` and `{{`
my_mean(mtcars, !!sym("cyl"))
See enquo0()
and enquos0()
for variants that don't enable
injection.
Defusing R expressions for an overview.
expr()
to defuse your own local expressions.
base::eval()
and eval_bare()
for resuming evaluation
of a defused expression.
# `enquo()` defuses the expression supplied by your user
f <- function(arg) {
enquo(arg)
}
f(1 + 1)
#> <quosure>
#> expr: ^1 + 1
#> env: 0x56240d26c740
# `enquos()` works with arguments and dots. It returns a list of
# expressions
f <- function(...) {
enquos(...)
}
f(1 + 1, 2 * 10)
#> <list_of<quosure>>
#>
#> [[1]]
#> <quosure>
#> expr: ^1 + 1
#> env: 0x56240d26c740
#>
#> [[2]]
#> <quosure>
#> expr: ^2 * 10
#> env: 0x56240d26c740
#>
# `enquo()` and `enquos()` enable _injection_ and _embracing_ for
# your users
g <- function(arg) {
f({{ arg }} * 2)
}
g(100)
#> <list_of<quosure>>
#>
#> [[1]]
#> <quosure>
#> expr: ^(^100) * 2
#> env: 0x56240cb8a5a0
#>
column <- sym("cyl")
g(!!column)
#> <list_of<quosure>>
#>
#> [[1]]
#> <quosure>
#> expr: ^(^cyl) * 2
#> env: 0x56240df3c2b0
#>