且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

将多个调用参数传递给dplyr自定义函数中的形式参数,而无需使用"...";

更新时间:2023-01-10 16:55:51

我们可以将...放在最后

foo <- function(data,  dv, ...){
   groups <- enquos(...)
   dv <- enquo(dv)
   data %>% 
     group_by(!!!groups) %>% 
     summarise(group_mean = mean(!!dv))
  }


如果我们要传递'group'的vector,则一个选项是group_by_at


If we want to pass a vector of 'group', then one option is group_by_at

foo <- function(data, groups, dv){
  dv <- enquo(dv)

  data %>% 
     group_by_at(vars(groups)) %>% 
     summarise(group_mean = mean(!!dv))
  }

mtcars %>% 
    foo(groups = c("vs", "am"), dv = mpg)
# A tibble: 4 x 3
# Groups:   vs [?]
#     vs    am group_mean
#  <dbl> <dbl>      <dbl>
#1     0     0       15.0
#2     0     1       19.8
#3     1     0       20.7
#4     1     1       28.4


如果我们想用c传递不带引号的表达式,一种选择是将其转换为表达式然后对其求值


One option if we want to pass unquoted expression with c would be to convert it to expression and then evaluate it

foo <- function(data, groups, dv){

 groups <- as.list(rlang::enexpr(groups))[-1]
 dv <- enquo(dv)
   data %>% 
      group_by(!!! groups) %>% 
      summarise(group_mean = mean(!!dv))
 }

mtcars %>% 
      foo(groups = c(vs, am), dv = mpg)
# A tibble: 4 x 3
# Groups:   vs [?]
#     vs    am group_mean
#  <dbl> <dbl>      <dbl>
#1     0     0       15.0
#2     0     1       19.8
#3     1     0       20.7
#4     1     1       28.4

或者如评论中提到的@Joe一样,enquo也应与group_by_at

Or as @Joe mentioned in the comments, enquo should also work with group_by_at

foo <- function(data, groups, dv){
   dv <- enquo(dv) 
   groups <- enquos(groups) 
   data %>% 
        group_by_at(vars(!!!groups)) %>% 
        summarise(group_mean = mean(!!dv))
   } 

mtcars %>% 
     foo(groups = c(vs, am), dv = mpg)
# A tibble: 4 x 3
# Groups:   vs [?]
#     vs    am group_mean
#  <dbl> <dbl>      <dbl>
#1     0     0       15.0
#2     0     1       19.8
#3     1     0       20.7
#4     1     1       28.4