r - 在自定义 dplyr 函数中更改结果变量的名称

标签 r function dplyr lazy-evaluation summary

背景

为了加快生成跨多个表的分组摘要;因为我在 dplyr 中做了大部分工作工作流,我起草了一个简单的函数来生成所需的指标

# Function to generate summary table
generate_summary_tbl <- function(dataset, group_column, summary_column) {
    group_column   <- enquo(group_column)
    summary_column <- enquo(summary_column)
    dataset %>% 
        group_by(!!group_column) %>% 
        summarise(
            mean = mean(!!summary_column),
            sum  = sum(!!summary_column)
            # Other metrics that need to be generated frequently
        ) %>% 
        ungroup -> smryDta
    return(smryDta)
}

例子

该函数按预期工作:

>> mtcars %>% 
...     generate_summary_tbl(group_column = am, summary_column = mpg)
# A tibble: 2 x 3
     am     mean   sum
  <dbl>    <dbl> <dbl>
1     0 17.14737 325.8
2     1 24.39231 317.1

问题

我希望有条件地在结果中包含通过 summary_column = mpg 传递的列的名称。

示例结果,useColName = TRUE

当使用 useColName = TRUE 调用时,结果应对应于:

>> mtcars %>% 
...     generate_summary_tbl(group_column = am, summary_column = mpg,
                             useColName = TRUE)
# A tibble: 2 x 3
     am     mean_am   sum_am
  <dbl>    <dbl>       <dbl>
1     0    17.14737    325.8
2     1    24.39231    317.1

不同之处在于变量名称 mean_am 中存在 _am 后缀,等等。

丑陋的解决方案

我使用的部分、丑陋的解决方案使用 setNames:

# Function to generate summary table
generate_summary_tbl <-
    function(dataset,
             group_column,
             summary_column,
             useColName = TRUE) {
        group_column   <- enquo(group_column)
        summary_column <- enquo(summary_column)
        dataset %>%
            group_by(!!group_column) %>%
            summarise(mean = mean(!!summary_column),
                      sum  = sum(!!summary_column)) %>%
            ungroup -> smryDta

        if (useColName) {
            setNames(smryDta,
                     c(deparse(substitute(
                         group_column
                     )),
                     paste(
                         names(smryDta)[2:length(smryDta)], paste0("_", deparse(substitute(
                             group_column
                         )))
                     ))) -> smryDta
        }

        return(smryDta)
    }

例子

返回的列名,几乎与期望的结果匹配。我想我可以使用一些正则表达式来达到预期的结果。但是,我认为应该有更有效的解决方案。

mtcars %>% 
    generate_summary_tbl(group_column = am, summary_column = mpg, useColName = TRUE)
# A tibble: 2 x 3
  `~am` `mean _~am` `sum _~am`
  <dbl>       <dbl>      <dbl>
1     0    17.14737      325.8
2     1    24.39231      317.1

如何获得所需的列名,最好是更好地利用 quolazyeval

最佳答案

也许使用重命名:

library(tidyverse)

generate_summary_tbl <- function(dataset, group_column, summary_column, useColname = FALSE) {
    group_column   <- enquo(group_column)
    summary_column <- enquo(summary_column)
    dataset %>% 
        group_by(!!group_column) %>% 
        summarise(
            mean = mean(!!summary_column),
            sum  = sum(!!summary_column)
            # Other metrics that need to be generated frequently
        ) %>% 
        ungroup -> smryDta

    if (useColname) 
      smryDta <- smryDta %>%  
      rename_at(
        vars(-one_of(quo_name(group_column))), 
        ~paste(quo_name(group_column), .x, sep="_")
      )

    return(smryDta)
}

mtcars %>% generate_summary_tbl(am, mpg)
# # A tibble: 2 x 3
#      am     mean   sum
#   <dbl>    <dbl> <dbl>
# 1     0 17.14737 325.8
# 2     1 24.39231 317.1
mtcars %>% generate_summary_tbl(am, mpg, T)
#   # A tibble: 2 x 3
#      am  am_mean am_sum
#   <dbl>    <dbl>  <dbl>
# 1     0 17.14737  325.8
# 2     1 24.39231  317.1

关于r - 在自定义 dplyr 函数中更改结果变量的名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45076971/

相关文章:

sql-server - 有没有办法将 sys.fn_varbintohexstr 结果转回 varbinary?

r - 如何使用 dplyr 管道一次性取消嵌套数据帧的多个列表列

r - 动态规范化组中第一个元素的所有行

r - dplyr 过滤器功能给出了错误的数据

r - 如何在 R 中的整个数据帧上使用正则表达式

使用 purrr 在一个数据集上运行多个 chisq 测试

r - 使用两个变量对数据进行子集化并对其进行汇总

c++ - 不使用 C++11 实现函数对象绑定(bind)

python - 函数参数概念

r - 有没有办法在绘图热图的右侧移动行标签?