rg4*_*g4s 6 r quote tidyverse rlang quasiquotes
有人可以解释一下,我们需要什么!!,!!!或者{{}}需要什么操作员吗rlang?我试图了解更多有关准引用的知识,但没有得到任何结果。
我已经在 Stack 上找到了几篇关于 curly-curly 运算符的帖子,并且了解我们{{在将数据帧的变量(或对象的其他子对象)传递到函数中时使用它。但在阅读了有关引用/取消引用的内容后,我对所有这些运算符及其用法完全感到困惑。
为什么我们需要它,为什么有些函数没有它就无法读取参数,最后,它们实际上是如何工作的?
如果您以最简单的方式给出答案,即使我也能理解(也许有例子?),我将不胜感激。
和运算符是占位符,用于!!将{{变量标记为已被引用。通常仅当您打算使用 进行编程时才需要它们tidyverse。\ntidyverse喜欢利用 NSE(非标准评估)来减少重复量。最常见的应用是针对"data.frame"类,其中在搜索其他范围之前在 data.frame 的上下文中评估表达式/符号。\n为了使其工作,一些特殊函数(例如在包中dplyr)具有以下参数:引。引用表达式,就是保存组成表达式的符号并防止求值(在tidyverse它们使用“quosures”的上下文中,它类似于引用的表达式,只不过它包含对表达式所在环境的引用)。 \n虽然 NSE 非常适合交互式使用,但使用它进行编程尤其困难。\n让我们考虑一下dplyr::select
library(dplyr)\n#> \n#> Attaching package: \'dplyr\'\n#> The following objects are masked from \'package:stats\':\n#> \n#> filter, lag\n#> The following objects are masked from \'package:base\':\n#> \n#> intersect, setdiff, setequal, union\n \n iris <- as_tibble(iris)\n \n my_select <- function(.data, col) {\n select(.data, col) \n }\n \n select(iris, Species)\n#> # A tibble: 150 \xc3\x97 1\n#> Species\n#> <fct> \n#> 1 setosa \n#> 2 setosa \n#> 3 setosa \n#> 4 setosa \n#> 5 setosa \n#> 6 setosa \n#> 7 setosa \n#> 8 setosa \n#> 9 setosa \n#> 10 setosa \n#> # \xe2\x80\xa6 with 140 more rows\n my_select(iris, Species)\n#> Error: object \'Species\' not found\nRun Code Online (Sandbox Code Playgroud)\nmy_select我们遇到错误,因为在\n范围内,col参数是使用标准计算进行计算的,\n无法找到名为 的变量Species。
如果我们尝试在全局环境中创建一个变量,我们会看到该函数可以工作 - 但它的行为不符合tidyverse. 事实上,\n他们会生成一条注释来通知您这是不明确的使用。
Species <- "Sepal.Width"\n my_select(iris, Species)\n#> Note: Using an external vector in selections is ambiguous.\n#> \xe2\x84\xb9 Use `all_of(col)` instead of `col` to silence this message.\n#> \xe2\x84\xb9 See <https://tidyselect.r-lib.org/reference/faq-external-vector.html>.\n#> This message is displayed once per session.\n#> # A tibble: 150 \xc3\x97 1\n#> Sepal.Width\n#> <dbl>\n#> 1 3.5\n#> 2 3 \n#> 3 3.2\n#> 4 3.1\n#> 5 3.6\n#> 6 3.9\n#> 7 3.4\n#> 8 3.4\n#> 9 2.9\n#> 10 3.1\n#> # \xe2\x80\xa6 with 140 more rows\nRun Code Online (Sandbox Code Playgroud)\n为了解决这个问题,我们需要\n防止使用 进行评估并enquo()取消引用!!或仅使用{{。
my_select2 <- function(.data, col) {\n col_quo <- enquo(col)\n select(.data, !!col_quo) #attempting to find whatever symbols were passed to `col` arugment\n }\n #\' `{{` enables the user to skip using the `enquo()` step.\n my_select3 <- function(.data, col) {\n select(.data, {{col}}) \n }\n \n my_select2(iris, Species)\n#> # A tibble: 150 \xc3\x97 1\n#> Species\n#> <fct> \n#> 1 setosa \n#> 2 setosa \n#> 3 setosa \n#> 4 setosa \n#> 5 setosa \n#> 6 setosa \n#> 7 setosa \n#> 8 setosa \n#> 9 setosa \n#> 10 setosa \n#> # \xe2\x80\xa6 with 140 more rows\n my_select3(iris, Species)\n#> # A tibble: 150 \xc3\x97 1\n#> Species\n#> <fct> \n#> 1 setosa \n#> 2 setosa \n#> 3 setosa \n#> 4 setosa \n#> 5 setosa \n#> 6 setosa \n#> 7 setosa \n#> 8 setosa \n#> 9 setosa \n#> 10 setosa \n#> # \xe2\x80\xa6 with 140 more rows\nRun Code Online (Sandbox Code Playgroud)\n总之,您实际上只需要!!并且{{如果您尝试以编程方式应用 NSE\ 或对该语言进行某种类型的编程。
!!!用于将某种类型的列表/向量拼接到某些引用表达式的参数中。
library(rlang)\n quo_let <- quo(paste(!!!LETTERS))\n quo_let\n#> <quosure>\n#> expr: ^paste("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L",\n#> "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y",\n#> "Z")\n#> env: global\n eval_tidy(quo_let)\n#> [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"\nRun Code Online (Sandbox Code Playgroud)\n由reprex 包(v2.0.1)创建于 2021-08-30
\n