在R语言中,特别是在!!sym("x")的上下文中,!!运算符是什么意思?

25
在R语言中,“!!”是一种解引用(unquote)的语法,它可以在代码中动态地插入变量或表达式的值。 在这个例子中,!!sym("x") 的作用是将字符串"x"转化为符号对象(symbol object)并获取它的值。如果不使用“!!”,则a将被分配为符号对象本身而不是它的值。在其他函数中,例如dplyr或tidyverse系列的函数,它们通常用于将参数动态地传递给函数。

3
你可以查看 help("!!") - akrun
2
https://youtu.be/nERXS3ssntw - Tung
1个回答

34

将字符串转换为符号后,它会打印不带引号的内容,但这并不是去引号的意思(我们会在结束时回到这点)。

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

那些方法行不通,因为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

!!本身并不起作用,也不是真正的运算符,但它告诉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

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

为什么它被称为不引用,可能更容易理解,通过查看这个等效调用:

quoted <- quote(Sepal.Width * 2)
dplyr::mutate(head(iris), !!quoted)

查看help("!!")获取更多详细信息。


1
"!!sym("y")"和"!!("y")"有什么区别?" - skan
3
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") 是相同的。 - moodymudskipper

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接