有什么用!!运算符 mean 在 R 中,尤其是在上下文中 !!sym("x")

mal*_*eta 9 r operators dplyr rlang

“!!”是什么意思 在 R 中做,为什么要使用它?

具体来说,我正在查看一个包含短语a = !!sym("x")where "x"is a string的函数 。我认为sym通过将字符串转换为对象来工作,因此a = sym("x")将设置为a等于 object x。有什么!!用?我读到它没有引用它后面的任何内容,但我认为sym它本身没有引用字符串?

我还看到!!与其他功能一起使用。它在做什么?

Moo*_*per 15

当您将字符串转换为符号时,它会在不带引号的情况下打印,但这不是不加引号的意思(我们将在最后返回)。

rlang::sym()正在从字符串创建一个符号,它几乎与base::as.symbol()(与此答案无关的微小差异)相同,它本身是 的别名base::as.name()

nm <- "Sepal.Width"
x <- rlang::sym(nm)
x
#> Sepal.Width
typeof(x)
#> [1] "symbol"
identical(x, as.symbol(nm))
#> [1] TRUE
Run Code Online (Sandbox Code Playgroud)

那些不起作用,因为xnm分别是符号和字符,所以我不能将它们乘以2

dplyr::mutate(head(iris),SW2 = nm * 2)
#> Error in nm * 2: argument non numérique pour un opérateur binaire
dplyr::mutate(head(iris),SW2 = x * 2)
#> Error in x * 2: argument non numérique pour un opérateur binaire
Run Code Online (Sandbox Code Playgroud)

!!它本身不做任何事情,也不是真正的操作员,但它告诉mutate()做某事,因为mutate()它旨在识别它。

它告诉的mutate()是表现得好像!!x被 x 的引用内容所取代。

# equivalent to dplyr::mutate(head(iris), Sepal.Width * 2)
dplyr::mutate(head(iris), !!x * 2)
#>   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> 1          5.1         3.5          1.4         0.2  setosa
#> 2          4.9         3.0          1.4         0.2  setosa
#> 3          4.7         3.2          1.3         0.2  setosa
#> 4          4.6         3.1          1.5         0.2  setosa
#> 5          5.0         3.6          1.4         0.2  setosa
#> 6          5.4         3.9          1.7         0.4  setosa
#>   Sepal.Width * 2
#> 1             7.0
#> 2             6.0
#> 3             6.4
#> 4             6.2
#> 5             7.2
#> 6             7.8
Run Code Online (Sandbox Code Playgroud)

dplyr::mutate(head(iris), !!sym("Sepal.Width") * 2) 会给出相同的输出。

通过查看另一个等效调用可能更容易理解为什么它被称为取消引用:

quoted <- quote(Sepal.Width * 2)
dplyr::mutate(head(iris), !!quoted)
Run Code Online (Sandbox Code Playgroud)

有关help("!!")更多详细信息,请参阅。

  • `bang_bang_aware_fun(!!"y")` 与 `bang_bang_aware_fun("y")` 相同。`bang_bang_aware_fun(!!sym("y"))` 与 `bang_bang_aware_fun(y)` 相同。如果 y 是字符串 `"something"`,`bang_bang_aware_fun(!!y)` 与 `bang_bang_aware_fun("something")` 相同 (3认同)
  • !!sym("y") 和 !!("y") 有什么区别? (2认同)