模仿 R 函数中的辅助整洁点参数

Mimicking a secondary tidy dots argument in an R function

我想创建一个函数,它接受(数据框)变量列表作为其参数之一。我设法使其部分工作,但是当我到达 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 none 的命令有效。他们都以 Error in !split : invalid argument type 结尾。如果没有 split 参数,f2(drat:qsec) 不会(立即)起作用,我对此并不感到惊讶,但是如何让第二条和第三条评论起作用?

第二个函数的问题(尽管缺少管道)是 count()(或者更确切地说 count() 调用的 group_by())不支持 tidyselect 语法,所以你不能像 select()gather() 等那样向它传递要拼接的列表。相反,一种选择是使用 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