使用 dplyr 编程:间接控制按哪些变量分组

Programming with dplyr: indirectly control by which variables to group by

我想编写一个简单的函数 f(grouping) 来汇总以下数据:

d0 <- data.frame(
  V1 = rep(1:5, times = 2),
  V2 = rep(2:6, times = 2),
  V3 = rep(11:15, times = 2),
  V4 = rep(12:16, times = 2),
  X = 1:10
)

我希望用户能够在两种分组之间进行选择:按 V1 或按 V2,因为用户可以写 f(grouping = V1)f(grouping = V2).但是,我希望它是这样的,如果 grouping = V1,它按 V1V3 分组。如果 grouping = V2,则按 V2V4 分组。请注意,由于 V3V4 最初的名称不直观,因此不应将它们用作函数调用的参数。

f(V1) 应该产生:

 # A tibble: 5 x 3
# Groups:   V1 [5]
     V1    V3     X
  <int> <int> <int>
1     1    11     7
2     2    12     9
3     3    13    11
4     4    14    13
5     5    15    15

f(V2)

# A tibble: 5 x 3
# Groups:   V2 [5]
     V2    V4     X
  <int> <int> <int>
1     2    12     7
2     3    13     9
3     4    14    11
4     5    15    13
5     6    16    15

我们使用 if/else 创建一个条件,以根据输入 grouping 的值连接 'V3' 或 'V4'。在函数内部,将不带引号的分组值转换为符号(ensym),再转换为字符串(as_string),然后使用if/else拼接组,将更新后的组('grp') 在 acrosssummarise 中 'X'

f1 <- function(data, grouping) {
        grp <- rlang::as_string(ensym(grouping))
        grp <- c(grp, if(grp == 'V1') 'V3' else 'V4')

        data %>%
            group_by(across(all_of(grp))) %>%
            summarise(X = sum(X), .groups = 'drop')

}

f1(d0, V1)
f1(d0, V2)