为什么 .env 代词在 dplyr::slice_max 中不起作用?

Gio*_*tti 4 r dplyr rlang

.env代词用来指代对象的环境(而不是一个data.frame内)以及内业等dplyr动词,但返回一个错误slice_max。为什么?考虑以下函数:


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
library(rlang)

f1 <- function(y) {
  d <- tibble(x = runif(20))
  d %>% 
    slice_max(order_by = .data$x, n = .env$y)
}

f2 <- function(y) {
  d <- tibble(x = runif(20))
  d %>% 
    filter(.data$x >= .env$y)
}

f3 <- function(y) {
  d <- tibble(x = runif(20))
  d %>% 
    mutate(z = .env$y)
}

f1(2)
#> Error: `n` must be a single number.
f2(0.8)
#> # A tibble: 8 x 1
#>       x
#>   <dbl>
#> 1 0.936
#> 2 0.812
#> 3 0.998
#> 4 0.962
#> 5 0.901
#> 6 0.875
#> 7 1.00 
#> 8 0.919
f3(2)
#> # A tibble: 20 x 2
#>         x     z
#>     <dbl> <dbl>
#>  1 0.0318     2
#>  2 0.928      2
#>  3 0.983      2
#>  4 0.622      2
#>  5 0.583      2
#>  6 0.0314     2
#>  7 0.481      2
#>  8 0.791      2
#>  9 0.476      2
#> 10 0.599      2
#> 11 0.468      2
#> 12 0.234      2
#> 13 0.276      2
#> 14 0.382      2
#> 15 0.914      2
#> 16 0.736      2
#> 17 0.572      2
#> 18 0.863      2
#> 19 0.337      2
#> 20 0.515      2
Run Code Online (Sandbox Code Playgroud)

reprex 包(v0.3.0)于 2020 年 11 月 16 日创建

All*_*ron 5

错误是从dplyr:::check_slice_size调用的函数中抛出的slice_max.data.frame。该函数的第 7:9 行是:

        if (!is.numeric(n) || length(n) != 1) {
            abort("`n` must be a single number.")
        }
Run Code Online (Sandbox Code Playgroud)

所以n必须是一个长度为一的数字。该.env代词没有在这里实现。

那么这是一个错误吗?我会争辩说它不是。.env这里不需要,因为n参数不使用 tidy 评估,也不应该使用它。由于只有n一个数字才有意义,因此使用 tidy 评估有意义的唯一情况是在单行小标题中。但是如果你知道你有一个单行的小标题,那么调用slice_max. 这是第 22 条规则:您唯一能够使用 tidy 评估的时间就是这样做没有用的时候。因此,这是一个很好的设计决策。

您可以放心,没有歧义。如果你y在这里使用,它总是按照你的意图解释.env$y

library(dplyr)
library(rlang)

f1 <- function(y) {
  d <- tibble(x = runif(20), y = rnorm(20))
  d %>% 
    slice_max(order_by = .data$x, n = y)
}

f1(2)
#> # A tibble: 2 x 2
#>       x      y
#>   <dbl>  <dbl>
#> 1 0.971 -1.65 
#> 2 0.918  0.151
Run Code Online (Sandbox Code Playgroud)

reprex 包(v0.3.0)于 2020 年 11 月 16 日创建