按聚合动态列名匹配进行分组

时间:2017-04-05 10:54:51

标签: r dplyr aggregate

是否可以使用dplyr group_by在列名上使用正则表达式匹配?

library(dplyr) # dplyr_0.5.0; R version 3.3.2 (2016-10-31)

# dummy data
set.seed(1)
df1 <-  sample_n(iris, 20) %>% 
  mutate(Sepal.Length = round(Sepal.Length),
         Sepal.Width = round(Sepal.Width))

静态版分组(看起来/工作正常,想象一下,如果我们有10-20列):

df1 %>% 
  group_by(Sepal.Length, Sepal.Width) %>% 
  summarise(mySum = sum(Petal.Length))

分组动态 - “丑陋”版本:

df1 %>% 
  group_by_(.dots = colnames(df1)[ grepl("^Sepal", colnames(df1))]) %>% 
  summarise(mySum = sum(Petal.Length))

理想情况下,这样的事情(不起作用,因为starts_with返回索引):

df1 %>% 
  group_by(starts_with("Sepal")) %>% 
  summarise(mySum = sum(Petal.Length))
Error in eval(expr, envir, enclos) : 
   wrong result size (0), expected 20 or 1

预期产出:

# Source: local data frame [6 x 3]
# Groups: Sepal.Length [?]
# 
#   Sepal.Length Sepal.Width mySum
#          <dbl>       <dbl> <dbl>
# 1            4           3   1.4
# 2            5           3  10.9
# 3            6           2   4.0
# 4            6           3  43.7
# 5            7           3  15.7
# 6            8           4   6.4

注意:听起来非常像重复的帖子,请将相关帖子链接起来。

2 个答案:

答案 0 :(得分:7)

此功能将在以后的版本中实现,参考GitHub issue #2619

解决方案是使用group_by_at函数:

df1 %>%
  group_by_at(vars(starts_with("Sepal"))) %>% 
  summarise(mySum = sum(Petal.Length))

修改:现在已在 dplyr_0.7.1

中实施

答案 1 :(得分:1)

如果您只想保留dplyr个功能,可以尝试:

df1 %>%
  group_by_(.dots = df1 %>% select(contains("Sepal")) %>% colnames()) %>%
  summarise(mySum = sum(Petal.Length))

虽然它不一定更漂亮,但它摆脱了正则表达式