problèmes dplyr lors de l'utilisation de group by (variables multiples)

je veux commencer à utiliser dplyr à la place de ddply mais je n'arrive pas à savoir comment ça marche (j'ai lu la documentation).

par exemple, pourquoi quand j'essaie de muter () quelque chose fait que la fonction "group_by" ne fonctionne pas comme il est supposé le faire?

en regardant mtcars:

library (car)

supposons que je fasse une donnée.cadre, qui est un résumé de mtcars, regroupés par "cyl" et "équipement":

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

Puis dire que je veux plus de résumer cette dataframe. Avec ddply, ce serait simple, mais quand j'essaie de faire avec avec dplyr, ce n'est pas vraiment "regroupement":

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

donne toujours une sortie non groupée:

  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

je fais quelque chose de mal avec la syntaxe?


Edit:

Si je devais le faire avec plyr et ddply:

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

et puis, pour obtenir le deuxième df:

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

mais cette même approche, avec somme (newvar) + 5 dans le résumer() ne fonctionne pas avec dplyr...

39
demandé sur smci 2014-02-09 03:50:36

5 réponses

poussant la réponse de Dickoa un peu plus loin -- comme Hadley le dit "résumez les pelures d'une seule couche de groupage". Il décolle de groupement dans l'ordre inverse dans lequel vous avez appliqué de sorte que vous pouvez simplement utiliser

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

Notez que cela vous donnera une réponse différente si vous utilisez group_by(gear, cyl) dans la deuxième ligne.

Et pour obtenir votre première tentative de travail:

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

df2 <- df1 %>%
 group_by(cyl) %>%
 summarise(newvar2 = sum(newvar)+5)
35
répondu Tim Cameron 2016-11-28 22:07:40

j'ai eu un problème similaire. J'ai trouvé que tout simplement détacher plyr résolu:

detach(package:plyr)    
library(dplyr)
61
répondu ManneR 2014-09-08 19:29:34

Si vous traduisez votre plyr code en dplyr en utilisant summarise au lieu de mutate vous obtenez les mêmes résultats.

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

Depuis summarise supprime le dernier groupe (gear), vous pouvez ignorer la deuxième group_by (voir @hadley commentaire ci-dessous)

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
répondu dickoa 2014-02-09 21:28:48

Détacher plyr est une façon de résoudre le problème donc vous pouvez utiliser dplyr fonctionne comme souhaité... mais que faire si vous avez besoin d'autres fonctions plyr pour effectuer d'autres tâches dans votre code?

(Dans cet exemple, j'ai deux dplyr et plyr bibliothèques chargés)

supposons que nous ayons une simple donnée.frame et nous voulons calculer la somme groupwise de la variable value, groupés par différents niveaux de 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

Mais quand nous essayons d'utiliser ce que nous croyons va produire un dplyr regroupés en somme, voici ce qui se passe:

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

il ne nous donne pas la réponse désirée. Probablement à cause d'une interaction ou d'une surcharge de group_by et ou mutate fonctions entre dplyr et plyr. On pourrait se détacher plyr, mais une autre façon est de donner un unique appel à dplyr versions de group_by et mutate:

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

maintenant, nous voyons que cela fonctionne comme prévu.

5
répondu Brett Borghetti 2015-02-27 02:14:41

dplyr fonctionne comme vous devriez vous y attendre dans votre exemple. Muter, comme vous l'avez spécifié, ajoutera juste 5 à chaque valeur de newvar comme il crée newvar2. Cela ressemblerait à la même chose si vous groupez ou non. Si, toutefois, vous spécifiez quelque chose qui diffère par groupe, vous obtiendrez quelque chose de différent. Par exemple:

df1 %.%
            group_by(cyl) %.%
            mutate(
                newvar2 = newvar + mean(cyl)
            )
4
répondu Vincent 2014-02-09 00:16:31