首页 > 解决方案 > 如何动态地 group_by 函数中的数据框变量?

问题描述

我想要一个函数,我可以在其中输入不同数量的列名并将它们分组。这里的第一段代码有效:

df <- data.frame(col_a = sample(1:10, 100, replace = T),
                      col_b = sample(letters, 100, replace = T),
                      col_c = sample(LETTERS, 100, replace = T))


my_fun = function(df, ...) {
  
  df %>% group_by_(...) %>% summarise(n = n())
}

my_fun(df , 'col_a')
my_fun(df , 'col_a', 'col_b')
my_fun(df , 'col_a', 'col_b', 'col_c')

我现在想要的是应用完整的函数,因此每个分组变量中的所有可能值都存在。我在下面的函数中手动输入了 col_acol_bcomplete()。不过,我想将可能的值作为函数参数传递,因为我并不总是按col_acol_b分组。

my_fun = function(df, ...) {
  
  df %>% group_by_(...) %>% summarise(count = n()) %>%
ungroup() %>%
complete(col_a = 1:10, col_b = letters, fill = list(count = 0))

}

my_fun(df , 'col_a', 'col_b')

标签: rdplyr

解决方案


您可以将数据捕获为命名列表。group_by+summarise n()可以替换为count.

library(tidyverse)

my_fun = function(df, ...) {
  args <- list(...)
  df %>% 
    count(across(all_of(names(args))), name = 'count') %>%
    complete(!!!args, fill = list(count = 0))
}

这可以运行为 -

my_fun(df , 'col_a' = 1:12)

#   col_a count
#   <int> <dbl>
# 1     1     9
# 2     2    15
# 3     3     4
# 4     4    11
# 5     5     7
# 6     6    12
# 7     7    12
# 8     8    10
# 9     9     5
#10    10    15
#11    11     0
#12    12     0


my_fun(df , 'col_a' = 1:10, 'col_b' = letters)

#  col_a col_b count
#   <int> <chr> <dbl>
# 1     1 a         1
# 2     1 b         0
# 3     1 c         0
# 4     1 d         0
# 5     1 e         0
# 6     1 f         1
# 7     1 g         0
# 8     1 h         0
# 9     1 i         0
#10     1 j         0
# … with 250 more rows

推荐阅读