首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在dplyr中按多个列分组,使用字符串向量输入

在dplyr中按多个列分组,使用字符串向量输入
EN

Stack Overflow用户
提问于 2014-01-19 03:26:51
回答 10查看 107.3K关注 0票数 168

我试图将我对plyr的理解转化为dplyr,但我不知道如何按多列进行分组。

代码语言:javascript
复制
# make data with weird column names that can't be hard coded
data = data.frame(
  asihckhdoydkhxiydfgfTgdsx = sample(LETTERS[1:3], 100, replace=TRUE),
  a30mvxigxkghc5cdsvxvyv0ja = sample(LETTERS[1:3], 100, replace=TRUE),
  value = rnorm(100)
)

# get the columns we want to average within
columns = names(data)[-3]

# plyr - works
ddply(data, columns, summarize, value=mean(value))

# dplyr - raises error
data %.%
  group_by(columns) %.%
  summarise(Value = mean(value))
#> Error in eval(expr, envir, enclos) : index out of bounds

要将plyr示例转换为dplyr-esque语法,我会遗漏什么?

编辑2017:Dplyr已经更新,因此可以使用更简单的解决方案。查看当前选择的答案。

EN

回答 10

Stack Overflow用户

回答已采纳

发布于 2017-07-07 00:46:53

自从这个问题发布后,dplyr添加了group_by的作用域版本(documentation here)。这使您可以使用与select相同的函数,如下所示:

代码语言:javascript
复制
data = data.frame(
    asihckhdoydkhxiydfgfTgdsx = sample(LETTERS[1:3], 100, replace=TRUE),
    a30mvxigxkghc5cdsvxvyv0ja = sample(LETTERS[1:3], 100, replace=TRUE),
    value = rnorm(100)
)

# get the columns we want to average within
columns = names(data)[-3]

library(dplyr)
df1 <- data %>%
  group_by_at(vars(one_of(columns))) %>%
  summarize(Value = mean(value))

#compare plyr for reference
df2 <- plyr::ddply(data, columns, plyr::summarize, value=mean(value))
table(df1 == df2, useNA = 'ifany')
## TRUE 
##  27 

您的示例问题的输出与预期一致(参见与上面的plyr和下面的输出的比较):

代码语言:javascript
复制
# A tibble: 9 x 3
# Groups:   asihckhdoydkhxiydfgfTgdsx [?]
  asihckhdoydkhxiydfgfTgdsx a30mvxigxkghc5cdsvxvyv0ja       Value
                     <fctr>                    <fctr>       <dbl>
1                         A                         A  0.04095002
2                         A                         B  0.24943935
3                         A                         C -0.25783892
4                         B                         A  0.15161805
5                         B                         B  0.27189974
6                         B                         C  0.20858897
7                         C                         A  0.19502221
8                         C                         B  0.56837548
9                         C                         C -0.22682998

请注意,由于dplyr::summarize一次只剥离了一层分组,因此在生成的tibble中仍然有一些分组正在进行(这有时会让人感到惊讶,后来会出人意料)。如果您想绝对安全地避免意外的分组行为,您始终可以在汇总之后将%>% ungroup添加到您的管道中。

票数 58
EN

Stack Overflow用户

发布于 2015-01-28 07:58:42

为了完整地编写代码,这里使用新语法更新Hadley的答案:

代码语言:javascript
复制
library(dplyr)

df <-  data.frame(
    asihckhdoydk = sample(LETTERS[1:3], 100, replace=TRUE),
    a30mvxigxkgh = sample(LETTERS[1:3], 100, replace=TRUE),
    value = rnorm(100)
)

# Columns you want to group by
grp_cols <- names(df)[-3]

# Convert character vector to list of symbols
dots <- lapply(grp_cols, as.symbol)

# Perform frequency counts
df %>%
    group_by_(.dots=dots) %>%
    summarise(n = n())

输出:

代码语言:javascript
复制
Source: local data frame [9 x 3]
Groups: asihckhdoydk

  asihckhdoydk a30mvxigxkgh  n
1            A            A 10
2            A            B 10
3            A            C 13
4            B            A 14
5            B            B 10
6            B            C 12
7            C            A  9
8            C            B 12
9            C            C 10
票数 105
EN

Stack Overflow用户

发布于 2014-01-21 04:42:31

目前在dplyr中对此的支持非常弱,最终我认为其语法将是这样的:

代码语言:javascript
复制
df %.% group_by(.groups = c("asdfgfTgdsx", "asdfk30v0ja"))

但这可能不会有一段时间(因为我需要考虑所有的后果)。

同时,您可以使用regroup(),它接受一个符号列表:

代码语言:javascript
复制
library(dplyr)

df <-  data.frame(
  asihckhdoydk = sample(LETTERS[1:3], 100, replace=TRUE),
  a30mvxigxkgh = sample(LETTERS[1:3], 100, replace=TRUE),
  value = rnorm(100)
)

df %.%
  regroup(list(quote(asihckhdoydk), quote(a30mvxigxkgh))) %.%
  summarise(n = n())

如果您有一个列名的字符矢量,可以使用lapply()as.symbol()将它们转换为正确的结构

代码语言:javascript
复制
vars <- setdiff(names(df), "value")
vars2 <- lapply(vars, as.symbol)

df %.% regroup(vars2) %.% summarise(n = n())
票数 58
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21208801

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档