在dplyr group_by中进行复杂列选择

5
我希望在group_by调用中使用dplyr的列选择器,例如starts_with()ends_with()matches()等语法,甚至包括-colName
以下是一个(傻瓜式)例子:
library("dplyr")

# I would like to do something like this
mtcars %>% 
   group_by(matches("a")) %>%
   summarise(mpg=mean(mpg))
# but I get a "wrong result size" error

我希望它能够工作,类比于:

mtcars %>% select(matches("a"))

这里需要选择列:drat、am、gear、carb

明确一点:我想使用 matches("a")(或等效代码)来达到与以下代码相同的输出:

mtcars %>% 
group_by(drat, am, gear, carb) %>%
summarise(mpg=mean(mpg))

我只对使用dplyr的答案感兴趣。谢谢!


当前的答案虽然不错,但只允许使用正则表达式选择列。

我仍在寻找一个更全面的答案,它将允许使用dplyr的全部选择语法范围。当然,我可以调整任何正则表达式来选择我想要的内容,但我希望有一些更好地与dplyr集成的东西(尤其是使用 -colName 语法)。我会把这个问题保留一段时间。

2个回答

5
这里有一个选项可以构建您自己的 group_at() 函数,我认为这个函数在 matches 和 SE 的 group_by_() 函数中不存在。
mtcars %>% 
      group_by_(.dots = names(mtcars)[matches("a", vars = names(mtcars))]) %>%
      summarise(mpg = mean(mpg))

#Source: local data frame [26 x 5]
#Groups: drat, am, gear [?]

#    drat    am  gear  carb   mpg
#   <dbl> <dbl> <dbl> <dbl> <dbl>
#1   2.76     0     3     1 18.10
#2   2.76     0     3     2 15.50
#3   2.93     0     3     4 10.40
#4   3.00     0     3     4 10.40
#5   3.07     0     3     3 16.30
#6   3.08     0     3     1 21.40
#7   3.08     0     3     2 19.20
#8   3.15     0     3     2 16.95
#9   3.21     0     3     4 14.30
#10  3.23     0     3     4 14.70
# ... with 16 more rows

或者等价地,只需使用grep

mtcars %>% 
      group_by_(.dots = grep('a', names(mtcars), value = TRUE)) %>%
      summarise(mpg=mean(mpg))

2
你可以使用 grep("a", names(mtcars), val=TRUE) 来避免对名称进行双重调用。 - Pierre L
@PierreLafortune 对,忘了那个。 - Psidom
非常感谢两位,我将把这个添加到我的便捷函数中!group_at <- function(df, pattern) group_by_(df, .dots=grep(names(df), pattern=pattern, value=T)) - asachet

0

group_by_at 函数在 2017 年的某个时候被添加到 dplyr 中,它可以实现分组聚合的功能。

mtcars %>% 
   group_by_at(matches("a")) %>%
   summarise(mpg=mean(mpg))

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