有什么作用!! R 中的运算符均值

2023-11-30

有人可以解释一下我们需要什么吗!!, !!! or {{}}运营商来自rlang?我尝试学习more关于准引用但没有得到任何东西。

我已经在 Stack 上找到了几篇关于 curly-curly 运算符的帖子,并且了解到我们使用{{当我们将数据帧的变量(或对象的其他子对象)传递到函数中时。但在阅读了有关引用/取消引用的内容后,我对所有这些运算符及其用法完全感到困惑。

为什么我们需要它,为什么有些函数没有它就无法读取参数,最后,它们实际上是如何工作的?

如果您以最简单的方式给出答案,即使我也能理解(也许有例子?),我将不胜感激。


The !! and {{运算符是占位符,用于将变量标记为已被引用。通常只有当您打算使用它们进行编程时才需要它们tidyverse. The tidyverse喜欢利用 NSE(非标准评估)来减少重复量。最常见的应用是针对"data.frame"类,其中在搜索其他范围之前在 data.frame 的上下文中评估表达式/符号。 为了让它工作,一些特殊的功能(比如在包dplyr) 有被引用的参数。引用一个表达式,就是保存组成该表达式的符号并防止求值(在tidyverse他们使用“quosures”,它类似于引用的表达式,只不过它包含对表达式所在环境的引用)。 虽然 NSE 非常适合交互式使用,但使用它进行编程却非常困难。 让我们考虑一下dplyr::select

 library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
 
 iris <- as_tibble(iris)
 
 my_select <- function(.data, col) {
   select(.data, col) 
 }
 
 select(iris, Species)
#> # A tibble: 150 × 1
#>    Species
#>    <fct>  
#>  1 setosa 
#>  2 setosa 
#>  3 setosa 
#>  4 setosa 
#>  5 setosa 
#>  6 setosa 
#>  7 setosa 
#>  8 setosa 
#>  9 setosa 
#> 10 setosa 
#> # … with 140 more rows
 my_select(iris, Species)
#> Error: object 'Species' not found

我们遇到错误,因为在范围内my_select the col论证是用标准评估来评估的 找不到名为的变量Species.

如果我们尝试在全局环境中创建一个变量,我们会看到该函数 有效 - 但它的行为不符合启发式tidyverse。实际上, 他们会制作一条注释,通知您这是不明确的使用。

 Species <- "Sepal.Width"
 my_select(iris, Species)
#> Note: Using an external vector in selections is ambiguous.
#> ℹ Use `all_of(col)` instead of `col` to silence this message.
#> ℹ See <https://tidyselect.r-lib.org/reference/faq-external-vector.html>.
#> This message is displayed once per session.
#> # A tibble: 150 × 1
#>    Sepal.Width
#>          <dbl>
#>  1         3.5
#>  2         3  
#>  3         3.2
#>  4         3.1
#>  5         3.6
#>  6         3.9
#>  7         3.4
#>  8         3.4
#>  9         2.9
#> 10         3.1
#> # … with 140 more rows

为了解决这个问题,我们需要 防止评估enquo()并取消引用!!或者只是使用{{.

 my_select2 <- function(.data, col) {
   col_quo <- enquo(col)
   select(.data, !!col_quo) #attempting to find whatever symbols were passed to `col` arugment
 }
 #' `{{` enables the user to skip using the `enquo()` step.
 my_select3 <- function(.data, col) {
   select(.data, {{col}}) 
 }
 
 my_select2(iris, Species)
#> # A tibble: 150 × 1
#>    Species
#>    <fct>  
#>  1 setosa 
#>  2 setosa 
#>  3 setosa 
#>  4 setosa 
#>  5 setosa 
#>  6 setosa 
#>  7 setosa 
#>  8 setosa 
#>  9 setosa 
#> 10 setosa 
#> # … with 140 more rows
 my_select3(iris, Species)
#> # A tibble: 150 × 1
#>    Species
#>    <fct>  
#>  1 setosa 
#>  2 setosa 
#>  3 setosa 
#>  4 setosa 
#>  5 setosa 
#>  6 setosa 
#>  7 setosa 
#>  8 setosa 
#>  9 setosa 
#> 10 setosa 
#> # … with 140 more rows

总而言之,你真的只需要!! and {{如果您尝试以编程方式应用 NSE 或者对该语言进行某种类型的编程。

!!!用于将某种类型的列表/向量拼接到某些引用表达式的参数中。

 library(rlang)
 quo_let <- quo(paste(!!!LETTERS))
 quo_let
#> <quosure>
#> expr: ^paste("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L",
#>           "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y",
#>           "Z")
#> env:  global
 eval_tidy(quo_let)
#> [1] "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z"

Created on 2021-08-30 by the reprex package (v2.0.1)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

有什么作用!! R 中的运算符均值 的相关文章

随机推荐