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

Why doesn't .env pronoun work inside dplyr::slice_max?

.env 代词用于指代环境中的对象(与 data.frame 中的对象相反)在其他 dplyr 动词中效果很好,但 returns [=13] 中的错误=].为什么? 考虑以下函数:


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

reprex package (v0.3.0)

于 2020-11-16 创建

错误是由 slice_max.data.frame 调用的函数 dplyr:::check_slice_size 引发的。该函数的第 7:9 行是:

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

所以 n 必须是 length-one 数字。 .env 代词未在此处实现。

这是一个错误吗?我会争辩说它不是。这里不需要 .env,因为 n 参数不使用 tidy 求值,也不应该使用。由于只有 n 是单个数字才有意义,因此使用整洁评估唯一有意义的情况是在 single-row tibble 中。但是如果你知道你有一个 single-row tibble,那么调用 slice_max 就没有意义了。这是一个陷阱 22:您唯一一次能够使用 tidy evaluation 的时候就是这样做没有用的时候。因此,这是一个很好的设计决策。

您放心,没有歧义。如果你在这里使用 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

reprex package (v0.3.0)

于 2020-11-16 创建