Как использовать dplyr
/ tidyselect
«выбор помощников», например :
, для выбора диапазона последовательных переменных в функциях, которые их не реализуют?
Если возможно, простым / элегантным способом (конечно это субъективно).
Вот пример с dplyr::distinct
, обратите внимание, что вопрос является общим c, хотя
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)