为什么 .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 创建
.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 创建