如何在不实现它们的函数中使用dplyr
/ tidyselect
“选择助手”,例如:
选择一系列连续变量?
如果可能以简单/优雅的方式(当然这是主观的)。
这是一个例子dplyr::distinct
,注意这个问题是通用的
library(dplyr)
mtcars %>%
distinct(vs:gear,
.keep_all = TRUE)
#> Warning in vs:gear: numerical expression has 32 elements: only the first used
#> Warning in vs:gear: numerical expression has 32 elements: only the first used
#> Error: Column `vs:gear` must be length 32 (the number of rows) or one, not 5
第一次尝试使用dplyr::select
. 我们能做得更好吗?
mtcars %>%
distinct(!!! syms(names(select(., vs:gear))),
.keep_all = TRUE)
#> mpg cyl disp hp drat wt qsec vs am gear carb
#> 1 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4
#> 2 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
#> 3 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1
#> 4 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2
#> 5 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2
#> 6 26.0 4 120.3 91 4.43 2.140 16.70 0 1 5 2
#> 7 30.4 4 95.1 113 3.77 1.513 16.90 1 1 5 2
基于https://tidyselect.r-lib.org/articles/tidyselect.html的第二次尝试,实际上感觉更糟
# With tidyselect >= 1.0
mtcars %>%
distinct(!!! syms(names(tidyselect::eval_select(quote(vs:gear), .))),
.keep_all = TRUE)
#> mpg cyl disp hp drat wt qsec vs am gear carb
#> 1 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4
#> 2 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
#> 3 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1
#> 4 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2
#> 5 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2
#> 6 26.0 4 120.3 91 4.43 2.140 16.70 0 1 5 2
#> 7 30.4 4 95.1 113 3.77 1.513 16.90 1 1 5 2
# Or equivalently
distinct2 <- function(.data, ..., .keep_all = FALSE) {
expr <- rlang::expr(c(...))
pos <- tidyselect::eval_select(expr, data = .data)
dplyr::distinct(.data = .data, .keep_all = .keep_all,
!!! syms(names(pos)))
}
mtcars %>%
distinct2(vs:gear, .keep_all = TRUE)