使用group_by(多个变量)时dplyr问题

时间:2014-02-08 23:50:37

标签: r group-by dplyr compound-key

我想开始使用dplyr代替ddply,但我无法理解它是如何工作的(我已阅读文档)。

例如,为什么当我尝试mutate()时,“group_by”函数不能正常工作?

看看mtcars:

库(汽车)

假设我创建了一个data.frame,它是mtcars的摘要,按“cyl”和“gear”分组:

df1 <- mtcars %.%
            group_by(cyl, gear) %.%
            summarise(
                newvar = sum(wt)
            )

然后说我想进一步总结这个数据帧。使用ddply,它会很简单,但是当我尝试使用dplyr时,它实际上并不是“分组”:

df2 <- df1 %.%
            group_by(cyl) %.%
            mutate(
                newvar2 = newvar + 5
            )

仍然产生未分组的输出:

  cyl gear newvar newvar2
1   6    3  6.675  11.675
2   4    4 19.025  24.025
3   6    4 12.375  17.375
4   6    5  2.770   7.770
5   4    3  2.465   7.465
6   8    3 49.249  54.249
7   4    5  3.653   8.653
8   8    5  6.740  11.740

我的语法有问题吗?


编辑:

如果我要用plyr和ddply这样做:

df1 <- ddply(mtcars, .(cyl, gear), summarise, newvar = sum(wt))

然后得到第二个df:

df2 <- ddply(df1, .(cyl), summarise, newvar2 = sum(newvar) + 5)

但同样的方法,在summarize()函数中使用sum(newvar)+ 5对dplyr不起作用...

5 个答案:

答案 0 :(得分:63)

我有类似的问题。我发现简单地分离plyr解决了它:

detach(package:plyr)    
library(dplyr)

答案 1 :(得分:39)

将Dickoa的答案更进一步 - 正如哈德利所说的那样“总结剥离了一层分组”。它会从您应用它的相反顺序剥离分组,因此您只需使用

即可
mtcars %>%
 group_by(cyl, gear) %>%
 summarise(newvar = sum(wt)) %>%
 summarise(newvar2 = sum(newvar) + 5)

请注意,如果您在第二行使用group_by(gear, cyl),则会给出不同的答案。

让你的第一次尝试工作:

df1 <- mtcars %>%
 group_by(cyl, gear) %>%
 summarise(newvar = sum(wt))

df2 <- df1 %>%
 group_by(cyl) %>%
 summarise(newvar2 = sum(newvar)+5)

答案 2 :(得分:10)

如果您使用plyr代替dplyrsummarise代码翻译为mutate,则会得到相同的结果。

library(plyr)
df1 <- ddply(mtcars, .(cyl, gear), summarise, newvar = sum(wt))
df2 <- ddply(df1, .(cyl), summarise, newvar2 = sum(newvar) + 5)
df2
##   cyl newvar2
## 1   4  30.143
## 2   6  26.820
## 3   8  60.989

detach(package:plyr)    
library(dplyr)
mtcars %.%
    group_by(cyl, gear) %.%
    summarise(newvar = sum(wt)) %.%
    group_by(cyl) %.%
    summarise(newvar2 = sum(newvar) + 5)
##   cyl newvar2
## 1   4  30.143
## 2   8  60.989
## 3   6  26.820

编辑

由于summarise删除了最后一个组(gear),您可以跳过第二个group_by(请参阅下面的@hadley评论)

library(dplyr)
mtcars %.%
    group_by(cyl, gear) %.%
    summarise(newvar = sum(wt)) %.%
    summarise(newvar2 = sum(newvar) + 5)
##   cyl newvar2
## 1   4  30.143
## 2   8  60.989
## 3   6  26.820

答案 3 :(得分:5)

分离plyr是解决问题的一种方法,因此您可以根据需要使用dplyr个功能......但如果您需要plyr中的其他功能来完成其他任务,该怎么办?码?

(在此示例中,我已加载dplyrplyr个库)

假设我们有一个简单的data.frame,我们想要计算变量value的分组总和,当按gname的不同级别分组时

> dx<-data.frame(gname=c(1,1,1,2,2,2,3,3,3), value = c(2,2,2,4,4,4,5,6,7))
> dx
  gname value
1     1     2
2     1     2
3     1     2
4     2     4
5     2     4
6     2     4
7     3     5
8     3     6
9     3     7

但是当我们尝试使用我们认为会产生dplyr分组总和的内容时,会发生什么:

dx %>% group_by(gname) %>% mutate(mysum=sum(value))
Source: local data frame [9 x 3]
Groups: gname

  gname value mysum
1     1     2    36
2     1     2    36
3     1     2    36
4     2     4    36
5     2     4    36
6     2     4    36
7     3     5    36
8     3     6    36
9     3     7    36

它没有给我们所需的答案。可能是因为group_bymutate之间的dplyr和/或plyr函数的某些交互或重载。我们可以分离plyr,但另一种方法是对dplyrgroup_by的{​​{1}}版本进行独特调用:

mutate

现在我们看到它按预期工作。

答案 4 :(得分:4)

dplyr正如您在示例中所期望的那样工作。正如你所指定的那样,Mutate只会在创建newvar2时为newvar的每个值加5。如果你是否分组,这看起来是一样的。但是,如果您指定的某些内容因组而异,则会得到不同的内容。例如:

df1 %.%
            group_by(cyl) %.%
            mutate(
                newvar2 = newvar + mean(cyl)
            )