Подражание вторичному аргументу аккуратных точек в функции R - PullRequest
1 голос
/ 25 февраля 2020

Я хочу создать функцию, которая принимает список переменных (фрейма данных) в качестве одного из своих параметров. Мне удалось заставить его работать частично, но когда я добираюсь до group_by / count, все рушится. Как я могу это сделать ??

## Works
f1 <- function(dfr, ..., split = NULL) {
  dots <- rlang::enquos(...)
  split <- rlang::enquos(split)
  dfr %>%
    select(!!!dots, !!!split) %>%
    gather('type', 'score', -c(!!!split))
}

## does not work
f2 <- function(dfr, ..., split = NULL) {
  dots <- rlang::enquos(...)
  split <- rlang::enquos(split)
  dfr %>%
    select(!!!dots, !!!split) %>%
    gather('type', 'score', -c(!!!split))
    count(!!!split, type, score)
  }

Я хотел бы сделать что-то вроде

mtcars %>% f2(drat:qsec)
mtcars %>% f2(drat:qsec, split = gear)
mtcars %>% f2(drat:qsec, split = c(gear, carb)) ## ??

Эти вызовы с f1() все работают, но для f2 ни одна из команд Работа. Все они в конечном итоге с Error in !split : invalid argument type. То, что f2(drat:qsec) (сразу) не работает без аргумента split, меня это не слишком удивляет, но как заставить работать второй и третий комментарий?

1 Ответ

1 голос
/ 26 февраля 2020

Проблема со второй функцией (несмотря на отсутствующий канал) заключается в том, что count() (или, скорее, group_by(), который вызывается count()) не поддерживает синтаксис tidyselect, поэтому вы не можете передать его в список соединяться, как вы можете с select(), gather() et c. Вместо этого одним из вариантов является использование group_by_at() и add_tally(). Вот немного измененная версия функции:

library(dplyr)

f2 <- function(dfr, ..., split = NULL) {
  dfr %>%
    select(..., {{split}}) %>%
    gather('type', 'score', -{{split}}) %>%
    group_by_at(vars({{split}}, type, score)) %>% # could use `group_by_all()`
    add_tally()
}

mtcars %>% f2(drat:qsec)

# A tibble: 96 x 3
# Groups:   type, score [81]
   type  score     n
   <chr> <dbl> <int>
 1 drat   3.9      2
 2 drat   3.9      2
 3 drat   3.85     1
 4 drat   3.08     2
 5 drat   3.15     2
 6 drat   2.76     2
 7 drat   3.21     1
 8 drat   3.69     1
 9 drat   3.92     3
10 drat   3.92     3
# ... with 86 more rows

mtcars %>% f2(drat:qsec, split = c(gear, carb))

# A tibble: 96 x 5
# Groups:   gear, carb, type, score [89]
    gear  carb type  score     n
   <dbl> <dbl> <chr> <dbl> <int>
 1     4     4 drat   3.9      2
 2     4     4 drat   3.9      2
 3     4     1 drat   3.85     1
 4     3     1 drat   3.08     1
 5     3     2 drat   3.15     2
 6     3     1 drat   2.76     1
 7     3     4 drat   3.21     1
 8     4     2 drat   3.69     1
 9     4     2 drat   3.92     1
10     4     4 drat   3.92     2
# ... with 86 more rows
...