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

3
我想编写一个简单的函数 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
)

我希望用户能够选择两种分类方式:通过V1V2进行分类。用户可以使用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
1个回答

3
我们使用 if/else 创建一个条件,根据输入的 grouping 值来连接 'V3' 或 'V4'。在函数内部,将未加引号的 grouping 值转换为符号 (ensym),然后转换为字符串 (as_string),然后使用 if/else 来连接这些组,并在 across 中传递更新的组 ('grp'),并使用 summarise 对 '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)

谢谢!你能否将你的答案适应于类似 f(d0, grouping = c(V1,V2) 的情况。出于某种原因,我收到了一个错误:只有字符串可以转换为符号 - Arthur Carvalho Brito
1
@ArthurCarvalhoBrito 如果你正在传递一个向量,那么最好传递字符串。c("V1", "V2")并且在函数内部,你不需要grp <- rlang::as_string(ensym(grouping)),而是可以使用grp <- c(grp, if('V1' %in% grouping) 'V3 else 'V4') - akrun
但是group_by可以用于字符串吗?我问这个问题是因为函数上有一个额外的参数,也选择了分组变量,但不需要间接添加与其连接的变量。所以最好有一些对称性。 - Arthur Carvalho Brito
1
@ArthurCarvalhoBrito 是的,如果你检查我的代码,它是 group_by(across(all_of(grp)),也就是说字符串可以在 across 中传递。 - akrun
1
以前,我们使用 group_by_at 并在内部传递 vars(grp),现在我们使用 acrossall_ofany_of(如果数据中不存在某些分组变量) - akrun

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接