Tidyeval与函数中的列名列表 [英] Tidyeval with list of column names in a function

查看:150
本文介绍了Tidyeval与函数中的列名列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创建一个将列名列表传递给dplyr函数的函数.如果...表单中给出了列名列表,我知道该怎么做,如tidyeval文档中所述:

I am trying to create a function that passes a list of column names to a dplyr function. I know how to do this if the list of columns names is given in the ... form, as explained in the tidyeval documentation:

df <- tibble(
  g1 = c(1, 1, 2, 2, 2),
  g2 = c(1, 2, 1, 2, 1),
  a = sample(5), 
  b = sample(5)
)

my_summarise <- function(df, ...) {
  group_var <- quos(...)

  df %>%
    group_by(!!!group_var) %>%
    summarise(a = mean(a))
}

my_summarise(df, g1, g2)

但是,如果我想将列名作为函数的参数列出,则上述解决方案将不起作用(当然):

But if I want to list the column names as an argument of the function, the above solution will not work (of course):

my_summarise <- function(df, group_var, sum_var) {
  group_var <- quos(group_var) # nor enquo(group_var)
  sum_var <- enquo(sum_var)

  df %>%
    group_by(!!!group_var) %>%
    summarise(a = mean(a))
}

my_summarise(df, list(g1, g2), a)
my_summarise(df, list(g1, g2), b)

如何获取列表中的项目以单独引用?

How can I get the items inside the list to be quoted individually?

此问题类似于在另一个函数内部的函数中传递数据框列名,但建议在注释中建议使用字符串,而在这里我想使用裸列名称.

This question is similar to Passing dataframe column names in a function inside another function but in the comments it was suggested to use strings, while here I would like to use bare column names.

推荐答案

您可以使用alist而不是list传递参数列表,因为它不会评估参数.

You could pass your list of arguments using alist instead of list, as it won't evaluate the arguments.

my_summarise = function(df, group_var, sum_var) {
    group_var = quos(!!! group_var)
    sum_var = enquo(sum_var)

    df %>%
        group_by(!!! group_var) %>%
        summarise(!! quo_name( sum_var) := mean( !! sum_var) )
}

my_summarise(df, alist(g1, g2), b)

# A tibble: 4 x 3
# Groups:   g1 [?]
     g1    g2     b
  <dbl> <dbl> <dbl>
1     1     1   2.0
2     1     2   3.0
3     2     1   4.5
4     2     2   1.0

另一种选择是直接使用quos而不是list传递该参数,如在此答案中所示 ,这一起绕开了一些并发症.

Another alternative would be to pass that argument directly with quos instead of list as shown in this answer, which bypasses some complications all together.

my_summarise = function(df, group_var, sum_var) {
    # group_var = quos(!!! group_var)
    sum_var = enquo(sum_var)

    df %>%
        group_by(!!! group_var) %>%
        summarise(!! quo_name( sum_var) := mean( !! sum_var) )
}

my_summarise(df, quos(g1, g2), b)

# A tibble: 4 x 3
# Groups:   g1 [?]
     g1    g2     b
  <dbl> <dbl> <dbl>
1     1     1   2.0
2     1     2   3.0
3     2     1   4.5
4     2     2   1.0

这篇关于Tidyeval与函数中的列名列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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