如何在R中传递...参数时保留!!运算符不被破坏?
... Arguments While Preserving rlang Injection (!!) Let's break down how to solve this problem, since match.call() doesn't play nicely with rlang's injection operators like !!.
The Issue with match.call()
When you use match.call(expand.dots = FALSE)$..., it captures the raw parse tree of your function call. That's why !!my_variable gets turned into !(!my_variable) — base R's match.call() just sees two separate negation operators instead of the injection syntax that rlang uses for tidy evaluation.
Solution 1: Keep the !! Expression Intact (Your "期望行为")
If you want to preserve the !!my_variable syntax in the output, use rlang::enquos() to capture the quoted arguments. This function is built to understand rlang's injection markers, so it won't break the !! syntax:
library(rlang) f <- function(...){ # Capture arguments as quosures to preserve injection syntax args <- enquos(...) # Extract just the expression part from each quosure lapply(args, quo_get_expr) } # Test it my_variable <- "my value" f(a = 1234, b = !!my_variable) #> $a #> [1] 1234 #> #> $b #> !!my_variable
Solution 2: Resolve the Injected Value (Your "更优期望")
If you want !!my_variable to expand to its actual value (so b returns "my value"), use rlang::list2() — it automatically handles injection in ... arguments:
f <- function(...){ list2(...) } my_variable <- "my value" f(a = 1234, b = !!my_variable) #> $a #> [1] 1234 #> #> $b #> [1] "my value"
For more control, you can also capture quosures and evaluate them explicitly with eval_tidy():
f <- function(...){ args <- enquos(...) lapply(args, eval_tidy) } f(a = 1234, b = !!my_variable) #> $a #> [1] 1234 #> #> $b #> [1] "my value"
The core idea here is that base R tools like match.call() don't recognize rlang's tidy evaluation syntax. Using rlang's purpose-built functions lets you properly handle injection operators in ... arguments without breaking their intended behavior.
内容的提问来源于stack exchange,提问作者landau

