使用 quasiquotation 将参数列表传递给函数 [英] Passing a list of arguments to a function with quasiquotation

查看:23
本文介绍了使用 quasiquotation 将参数列表传递给函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 R 中编写一个函数,该函数根据分组变量汇总数据框.分组变量作为列表给出并传递给 group_by_at,我想对它们进行参数化.

I am trying to write a function in R that summarizes a data frame according to grouping variables. The grouping variables are given as a list and passed to group_by_at, and I would like to parametrize them.

我现在正在做的是:

library(tidyverse)

d = tribble(
  ~foo, ~bar, ~baz,
  1, 2, 3,
  1, 3, 5
  4, 5, 6,
  4, 5, 1
)

sum_fun <- function(df, group_vars, sum_var) {
  sum_var = enquo(sum_var)
  return(
    df %>% 
      group_by_at(.vars = group_vars) %>% 
      summarize(sum(!! sum_var))
  )
}

d %>% sum_fun(group_vars = c("foo", "bar"), baz)

但是,我想像这样调用函数:

However, I would like to call the function like so:

d %>% sum_fun(group_vars = c(foo, bar), baz)

这意味着不应在调用中评估分组变量,而应在函数中评估.我将如何重写函数以启用它?

Which means the grouping vars should not be evaluated in the call, but in the function. How would I go about rewriting the function to enable that?

我尝试过使用 enquo 就像用于摘要变量一样,然后用 替换 group_vars !!group_vars,但会导致此错误:

I have tried using enquo just like for the summary variable, and then replacing group_vars with !! group_vars, but it leads to this error:

Error in !group_vars : invalid argument type

使用 group_by(!!!group_vars) 产生:

Column `c(foo, bar)` must be length 2 (the number of rows) or one, not 4 

重写函数的正确方法是什么?

What would be the proper way to rewrite the function?

推荐答案

您可以使用dplyr::group_by()dplyr::across()<的组合来重写该函数/code> 和 卷曲拥抱 {{.这适用于 dplyr 1.0.0 及更高版本.

You can rewrite the function using a combination of dplyr::group_by(), dplyr::across(), and curly curly embracing {{. This works with dplyr version 1.0.0 and greater.

为了清晰起见,我编辑了原始示例和代码.

I've edited the original example and code for clarity.

library(tidyverse)

my_data <- tribble(
  ~foo, ~bar, ~baz,
   "A",  "B",    3,
   "A",  "C",    5,
   "D",  "E",    6,
   "D",  "E",    1
)

sum_fun <- function(.data, group, sum_var) {
    .data %>% 
      group_by(across({{ group }})) %>% 
      summarize("sum_{{sum_var}}" := sum({{ sum_var }}))
}

sum_fun(my_data, group = c(foo, bar), sum_var = baz)
#> `summarise()` has grouped output by 'foo'. You can override using the `.groups` argument.
#> # A tibble: 3 x 3
#> # Groups:   foo [2]
#>   foo   bar   sum_baz
#>   <chr> <chr>   <dbl>
#> 1 A     B           3
#> 2 A     C           5
#> 3 D     E           7

reprex 包 (v2.0.0) 于 2021 年 9 月 6 日创建

Created on 2021-09-06 by the reprex package (v2.0.0)

这篇关于使用 quasiquotation 将参数列表传递给函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆