弯曲的弯曲的整理评估和修改输入或其名称

8

本文介绍了新的整洁求值(tidy evaluation)方法,详见此文。文章举了几个例子,展示了这种非标准求值(NSE)风格的使用。

library(tidyverse)

# Example 1 --------------------------
max_by <- function(data, var, by) {
  data %>%
    group_by({{ by }}) %>%
    summarise(maximum = max({{ var }}, na.rm = TRUE))
}
starwars %>% max_by(height)
starwars %>% max_by(height, by = gender)

# Example 2 --------------------------
summarise_by <- function(data, ..., by) {
  data %>%
    group_by({{ by }}) %>%
    summarise(...)
}

starwars %>%
  summarise_by(average = mean(height, na.rm = TRUE),
               maximum = max(height, na.rm = TRUE),
               by = gender)

我创建了一些自己的函数,这确实是一个更容易开发的框架,而不必担心所有的quosures和bangs之类的问题。

然而,同一篇文章解释说,我们还没有完全摆脱困扰:

只有在需要以某种方式修改输入或其名称时,才需要使用quote-and-unquote(以及复数变种enquos()和!!!)。

...但没有提供示例。不是抱怨,只是询问是否有人可以填补间隙并提供一个示例。由于不熟悉整洁评估,我真的不明白作者在引用中想表达什么意思。


假设您想创建一个格式为 summarise(colNm := 的列,您可能需要使用 !! - akrun
你的问题不够具体,因此很难回答。 - akrun
@akrun,我正在寻找_curly curly_ Tidy评估的示例,其中我将被迫使用enquos()!!!。最好能看到每个单独使用的示例。我希望它在参考文章中,但实际上并没有。 - Display name
我之所以说它很广泛,是因为如果我举一个例子,另一个人就会举出其他的情况。 - akrun
1
@akrun,我通常会等待24小时,然后选择最能展示我所寻找的概念的答案进行点赞并标记为已解决。你一直是一个很好的帮助者,我知道当其他人的例子和评论争吵时,你曾经感到过沮丧。请不要把任何事情都当成个人攻击。大多数人在这里都在努力编写更好的代码,我只能相信你也是。谢谢。 - Display name
显示剩余3条评论
1个回答

7

假设你想要一个版本的以下函数,它可以接收多个输入而不仅仅是单个的 var

mean_by <- function(data, var, by) {
  data %>%
    group_by({{ by }}) %>%
    summarise(average = mean({{ var }}, na.rm = TRUE))
}

你不能仅仅传递 ... 给summarise函数,因为这样用户需要自行调用mean()

mean_by <- function(data, var, ..., by) {
  data %>%
    group_by({{ by }}) %>%
    summarise(...)
}

mtcars %>% mean_by(foo = disp)
#> Error: Column `foo` must be length 1 (a summary value), not 32

mtcars %>% mean_by(foo = mean(disp))
#> # A tibble: 1 x 1
#>     foo
#>   <dbl>
#> 1  231.

解决方案是引用圆点,修改每个输入,使其包含在一个新的 mean() 调用中,然后再将它们拼接回去。
mean_by <- function(data, ..., by) {
  # `.named` makes sure the dots have default names, if not supplied
  dots <- enquos(..., .named = TRUE)

  # Go over all inputs, and wrap them in a call
  dots <- lapply(dots, function(dot) call("mean", dot, na.rm = TRUE))

  # Finally, splice the expressions back into `summarise()`:
  data %>%
    group_by({{ by }}) %>%
    summarise(!!!dots)
}

我们正在考虑如何改善这种情况的语法。早期想法在http://rpubs.com/lionel-/superstache上。

5
"这个(超级胡子)运算符将使得一些新的模式得以实现,而这些模式目前需要掌握元编程技巧才能实现,例如引用输入、创建调用等。" 好的,请在下一个版本的 rlang 中实现这个超级胡子,让元编程仍然保持“高级”的水平,同时允许中级用户通过使用 {{{ }}} 来成为 TidyEval 忍者。我可以很容易地记住双花括号和三花括号,但我几乎不记得 quosure、quoture、bang、bang bang ting tang walla walla bing bang 中的任何内容。 - Display name
@Lionel 一年后有任何更新吗?我在谷歌搜索“dplyr superstache”或检查编程文献中没有找到任何新的信息。 - lost

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