首页 文章

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

提问于
浏览
40

我想开始使用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 回答

  • 4

    将Dickoa的答案更进一步 - 正如Hadley所说的那样“总结剥离了一层分组” . 它会从您应用它的相反顺序剥离分组,以便您可以使用它

    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)
    
  • 37

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

    detach(package:plyr)    
    library(dplyr)
    
  • 5

    如果您使用 summarise 而不是 mutateplyr 代码转换为 dplyr ,则会得到相同的结果 .

    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
    

    EDIT

    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
    
  • 10

    分离 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
    

    它没有给我们想要的答案 . 可能是因为 dplyrplyr 之间的 group_by 和/或 mutate 函数的某些交互或重载 . 我们可以分离 plyr ,但另一种方法是对 group_bymutatedplyr 版本进行唯一调用:

    dx %>% dplyr::group_by(gname) %>% dplyr::mutate(mysum=sum(value))
    Source: local data frame [9 x 3]
    Groups: gname
    
      gname value mysum
    1     1     2     6
    2     1     2     6
    3     1     2     6
    4     2     4    12
    5     2     4    12
    6     2     4    12
    7     3     5    18
    8     3     6    18
    9     3     7    18
    

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

  • 61

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

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

相关问题