卷曲Tidy评估和修改输入或其名称

Jas*_*ter 5 r non-standard-evaluation tidyeval rlang

本文阐述了一种新的卷曲卷曲整洁评价方法。给出了几个示例,说明了这种风格的非标准评估(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)
Run Code Online (Sandbox Code Playgroud)

我创建了一些自己的函数,实际上这是一个更容易开发的框架,而不用担心所有的夸张和爆炸。

但是,同一篇文章说明我们还没有完全走出困境:

当您需要以某种方式修改输入或输入名称时,只需要使用引号和取消引号(带有复数形式的enquos()和!!!)。

...,但未提供示例。不抱怨,只是问是否有人可以填补空白并提供示例。由于我对Tidy的评估不流利,所以我真的不明白作者对那句话的理解(对不起)

Lio*_*nry 6

假设您需要以下函数的版本,该版本需要多个输入而不是一个输入var

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

您不能仅仅...进行总结,因为那样的话,用户需要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.
Run Code Online (Sandbox Code Playgroud)

解决方案是用引号引起来,修改每个输入,以便将它们包装在对的新调用中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)
}
Run Code Online (Sandbox Code Playgroud)

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

  • _“此(超精简)运算符将启用当前无法学习的新模式,除非学习元编程,例如引用输入,创建调用等。” _是的。请在下一版本的rlang中实现此超级方法。让元编程保持“高级”,同时通过使用此“ {{{}}}”允许中间用户仍然是忍者。我可以很容易地记得两次卷曲和三次卷曲,而我几乎不记得报价单中的报价来自一声轰隆的一声。 (2认同)