dplyr group_by中的复杂列选择

asa*_*ica 4 r dataframe dplyr

我想用,一个内group_by通话,dplyr的列选择喜欢starts_with()ends_with()matches(),...,甚至语法-colName

(Silly)我遵循的语法示例:

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
Run Code Online (Sandbox Code Playgroud)

我希望通过类似的方式它可以工作:

mtcars %>% select(matches("a"))
Run Code Online (Sandbox Code Playgroud)

这里将选择列 drat, am, gear, carb

明确地说:我想使用matches("a")(或等效方法)实现与以下相同的输出:

mtcars %>% 
group_by(drat, am, gear, carb) %>%
summarise(mpg=mean(mpg))
Run Code Online (Sandbox Code Playgroud)

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


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

我仍在寻找更全面的答案,以允许使用dplyr的选择语法的全部范围。当然,我可以对任何正则表达式进行按摩,以选择所需的内容,但我希望我拥有一些可以更好地与dplyr集成的东西(尤其是使用-colName语法)。我要暂时打开它。

Psi*_*dom 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
Run Code Online (Sandbox Code Playgroud)

或者等效地,只需使用grep

mtcars %>% 
      group_by_(.dots = grep('a', names(mtcars), value = TRUE)) %>%
      summarise(mpg=mean(mpg))
Run Code Online (Sandbox Code Playgroud)

  • 您可以避免通过`grep(“ a”,names(mtcars),val = TRUE)重复调用名称。 (2认同)

asa*_*ica 0

group_by_at于 2017 年的某个时候被添加到 dplyr 中,并且就是这样做的。

mtcars %>% 
   group_by_at(matches("a")) %>%
   summarise(mpg=mean(mpg))
Run Code Online (Sandbox Code Playgroud)