Skip to content

enquo() and enquos() defuse function arguments. A defused expression can be examined, modified, and injected into other expressions.

Defusing function arguments is useful for:

These are advanced tools. Make sure to first learn about the embrace operator {{ in Data mask programming patterns. {{ is easier to work with less theory, and it is sufficient in most applications.

Usage

enquo(arg)

enquos(
  ...,
  .named = FALSE,
  .ignore_empty = c("trailing", "none", "all"),
  .ignore_null = c("none", "all"),
  .unquote_names = TRUE,
  .homonyms = c("keep", "first", "last", "error"),
  .check_assign = FALSE
)

Arguments

arg

An unquoted argument name. The expression supplied to that argument is defused and returned.

...

Names of arguments to defuse.

.named

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.

.ignore_empty

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.

.ignore_null

Whether to ignore unnamed null arguments. Can be "none" or "all".

.unquote_names

Whether to treat := as =. Unlike =, the := syntax supports names injection.

.homonyms

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.

.check_assign

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.

Value

enquo() returns a quosure and enquos()

returns a list of quosures.

Implicit injection

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.

See also

Examples

# `enquo()` defuses the expression supplied by your user
f <- function(arg) {
  enquo(arg)
}

f(1 + 1)
#> <quosure>
#> expr: ^1 + 1
#> env:  0x556760516be8

# `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:  0x556760516be8
#> 
#> [[2]]
#> <quosure>
#> expr: ^2 * 10
#> env:  0x556760516be8
#> 


# `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:  0x556761585710
#> 

column <- sym("cyl")
g(!!column)
#> <list_of<quosure>>
#> 
#> [[1]]
#> <quosure>
#> expr: ^(^cyl) * 2
#> env:  0x556762af7e08
#>