Как избежать многоточия ... в dplyr? - PullRequest
3 голосов
/ 06 января 2020

Я хочу создать функцию, которая принимает аргумент группировки. Который может быть одной или несколькими переменными. Я хочу, чтобы это выглядело так:

wanted <- function(data, groups, other_params){
  data %>% group_by( {{groups}} ) %>% count()
}

Это работает только тогда, когда дается одна группа, но прерывается, когда есть несколько групп. Я знаю, что можно использовать следующее с многоточием ... (но мне нужен синтаксис groups = something):

not_wanted <- function(data, ..., other_params){
  data %>% group_by( ... ) %>% count()
}

Вот весь код:

library(dplyr)
library(magrittr)

iris$group2 <- rep(1:5, 30)

wanted <- function(data, groups, other_params){
  data %>% group_by( {{groups}} ) %>% count()
}

not_wanted <- function(data, ..., other_params){
  data %>% group_by( ... ) %>% count()
}

# works
wanted(iris, groups = Species )
not_wanted(iris, Species, group2)

# doesn't work
wanted(iris, groups = vars(Species, group2) )
wanted(iris, groups = c(Species, group2) )
wanted(iris, groups = vars("Species", "group2") )
#  Error: Column `vars(Species, group2)` must be length 150 (the number of rows) or one, not 2

Ответы [ 3 ]

5 голосов
/ 06 января 2020

Вы, ребята, слишком много усложняете, это прекрасно работает:

library(tidyverse)

wanted <- function(data, groups){
  data %>%  count(!!!groups)
}

mtcars %>% wanted(groups = vars(mpg,disp,hp))

# A tibble: 31 x 4
     mpg  disp    hp     n
   <dbl> <dbl> <dbl> <int>
 1  10.4  460    215     1
 2  10.4  472    205     1
 3  13.3  350    245     1
 4  14.3  360    245     1
 5  14.7  440    230     1
 6  15    301    335     1
 7  15.2  276.   180     1
 8  15.2  304    150     1
 9  15.5  318    150     1
10  15.8  351    264     1
# … with 21 more rows
0 голосов
/ 06 января 2020

Вот еще один вариант, чтобы избежать кавычек в вызове функции. Я признаю, что это не очень красиво, хотя.

library(tidyverse)

wanted <- function(data, groups){
  grouping <- gsub(x = rlang::quo_get_expr(enquo(groups)), pattern = "\\((.*)?\\)", replacement = "\\1")[-1]
  data %>% group_by_at(grouping) %>% count()
}


iris$group2 <- rep(1:5, 30)

wanted(iris, groups = c(Species, group2) )
#> # A tibble: 15 x 3
#> # Groups:   Species, group2 [15]
#>    Species    group2     n
#>    <fct>       <int> <int>
#>  1 setosa          1    10
#>  2 setosa          2    10
#>  3 setosa          3    10
#>  4 setosa          4    10
#>  5 setosa          5    10
#>  6 versicolor      1    10
#>  7 versicolor      2    10
#>  8 versicolor      3    10
#>  9 versicolor      4    10
#> 10 versicolor      5    10
#> 11 virginica       1    10
#> 12 virginica       2    10
#> 13 virginica       3    10
#> 14 virginica       4    10
#> 15 virginica       5    10
0 голосов
/ 06 января 2020

Оператор тройного взрыва и parse_quos из пакета rlang добьются цели. Для получения дополнительной информации см., Например, { ссылка }

library(dplyr)

library(magrittr)

iris$group2 <- rep(1:5, 30)


vec <- c("Species", "group2")


wanted <- function(data, groups){
  data %>%  count(!!!rlang::parse_quos(groups, rlang::current_env()))
}

wanted(iris, vec)
#> # A tibble: 15 x 3
#>    Species    group2     n
#>    <fct>       <int> <int>
#>  1 setosa          1    10
#>  2 setosa          2    10
#>  3 setosa          3    10
#>  4 setosa          4    10
#>  5 setosa          5    10
#>  6 versicolor      1    10
#>  7 versicolor      2    10
#>  8 versicolor      3    10
#>  9 versicolor      4    10
#> 10 versicolor      5    10
#> 11 virginica       1    10
#> 12 virginica       2    10
#> 13 virginica       3    10
#> 14 virginica       4    10
#> 15 virginica       5    10

Создано в 2020-01-06 пакетом Представить (v0.3.0)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...