将列名作为字符串传递给group_by和summarize函数

18

从dplyr 0.7版本开始,以下划线结尾的方法(如summarize_ group_by_)已经被弃用,因为我们应该使用quosures。

参见: https://cran.r-project.org/web/packages/dplyr/vignettes/programming.html

我正在尝试使用quo和!!实现以下示例:

可以正常工作的示例:

df <- data.frame(x = c("a","a","a","b","b","b"), y=c(1,1,2,2,3,3), z = 1:6)

lFG <- df %>% 
   group_by( x,y) 
lFG %>% summarize( min(z))
然而,在这种情况下,我需要实现按组进行分组和汇总的列被指定为字符串。
cols2group <- c("x","y")
col2summarize <- "z"

我该如何让上述示例运行起来?

4个回答

19

现在您可以使用带有_at的动词版本来实现此操作。

df %>%  
  group_by_at(cols2group) %>% 
  summarize_at(.vars = col2summarize, .funs = min)

编辑(2021年06月09日):

请参考Ronak Shah的答案,使用

mutate(across(all_of(cols2summarize), min))

现在首选的选项


11

dplyr 1.0.0 开始,您可以使用 across

library(dplyr)

cols2group <- c("x","y")
col2summarize <- "z"

df %>%
  group_by(across(all_of(cols2group))) %>%
  summarise(across(all_of(col2summarize), min)) %>%
  ungroup

#   x       y     z
#  <chr> <dbl> <int>
#1 a         1     1
#2 a         2     3
#3 b         2     4
#4 b         3     5

1
为什么你需要在across中使用all_of?我没有使用它也能正常工作。而且它适用于Spark! - kael
5
它将按预期运行,但会给出一个警告(每个会话一次):注意:在选择中使用外部向量是含糊的。ℹ 使用'all_of(cols2group)'代替'cols2group'可以消除此消息。 - Ronak Shah

4

另一种选择是使用非标准评估(NSE),让 R 解释字符串为对象名称的引用:

cols2group <- c("x","y")
col2summarize <- "z"

df %>%  
  group_by(!!rlang::sym(cols2group)) %>% 
  summarize(min(!!rlang::sym(col2summarize)))

rlang::sym() 函数将字符串转换为引用,这些引用由 !! 解除引用,并在 df 上下文中用作名称,它们引用相关列。总是有不同的方式来做相同的事情,而这是我倾向于使用的简写方式!


1

请参见 ?dplyr::across,因为 group_by_at 和 summarize_at 现已过时,需要更新的方法


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