19.4 Unquote

  • Unquoting allows you to merge together ASTs with selective evaluation.

  • Use !! (inject operator)

  • One argument

# quote `-1` as `x`
x <- rlang::expr(-1)
# unquote `x` to substitute its unquoted value
# use bang-bang operator
res = rlang::expr(f(!!x, y))
print(res)
#> f(-1, y)
lobstr::ast(!!res)
#> █─f 
#> ├─█─`-` 
#> │ └─1 
#> └─y
  • If the right-hand side of !! is a function call, it will evalute the function and insert the results.
mean_rm <- function(var) {
  var <- ensym(var)
  expr(mean(!!var, na.rm = TRUE))
}
expr(!!mean_rm(x) + !!mean_rm(y))
#> mean(x, na.rm = TRUE) + mean(y, na.rm = TRUE)
#> mean(x, na.rm = TRUE) + mean(y, na.rm = TRUE)
  • Multiple arguments, use !!! Splice
xs <- rlang::exprs(1, a, -b)
# unquote multiple arguments
# use bang-bang-bang operator
res=expr(f(!!!xs, y))
res
#> f(1, a, -b, y)
lobstr::ast(!!res)
#> █─f 
#> ├─1 
#> ├─a 
#> ├─█─`-` 
#> │ └─b 
#> └─y