Je veux commencer à utiliser dplyr à la place de ddply mais je ne peux pas comprendre comment cela fonctionne (j'ai lu la documentation).
Par exemple, pourquoi quand j'essaie de muter () quelque chose, la fonction "group_by" ne fonctionne-t-elle pas comme prévu?
En regardant mtcars:
bibliothèque (voiture)
Dites que je fais un data.frame qui est un résumé de mtcars, regroupés par "cyl" et "gear":
df1 <- mtcars %.%
group_by(cyl, gear) %.%
summarise(
newvar = sum(wt)
)
Ensuite, disons que je veux résumer davantage cette base de données. Avec ddply, ce serait simple, mais lorsque j'essaie de le faire avec dplyr, ce n'est pas réellement "grouper par":
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
Est-ce que je fais quelque chose de mal avec la syntaxe?
Modifier:
Si je devais le faire avec plyr and ddply:
df1 <- ddply(mtcars, .(cyl, gear), summarise, newvar = sum(wt))
et ensuite pour obtenir le deuxième df:
df2 <- ddply(df1, .(cyl), summarise, newvar2 = sum(newvar) + 5)
Mais cette même approche, avec sum (newvar) + 5 dans la fonction resume (), ne fonctionne pas avec dplyr ...
Prenant la réponse de Dickoa un peu plus loin - comme le dit Hadley, "résumez les pelures d'une seule couche de groupement". Il se détache du regroupement à partir de l’ordre inverse dans lequel vous l’avez appliqué afin que vous puissiez simplement utiliser
mtcars %>%
group_by(cyl, gear) %>%
summarise(newvar = sum(wt)) %>%
summarise(newvar2 = sum(newvar) + 5)
Notez que cela donnera une réponse différente si vous utilisez group_by(gear, cyl)
à la deuxième ligne.
Et pour réussir votre première tentative:
df1 <- mtcars %>%
group_by(cyl, gear) %>%
summarise(newvar = sum(wt))
df2 <- df1 %>%
group_by(cyl) %>%
summarise(newvar2 = sum(newvar)+5)
J'avais un problème similaire. J'ai découvert que le simple détachement de plyr
le résolvait:
detach(package:plyr)
library(dplyr)
Si vous traduisez votre code plyr
en dplyr
à l'aide de 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
Puisque summarise
supprime le dernier groupe (gear
), vous pouvez ignorer le second group_by
_ (voir le commentaire @hadley 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
Détacher plyr
est un moyen de résoudre le problème afin que vous puissiez utiliser les fonctions dplyr
à votre guise ... mais si vous avez besoin d'autres fonctions de plyr
pour effectuer d'autres tâches code?
(Dans cet exemple, les bibliothèques dplyr
et plyr
sont chargées)
Supposons que nous ayons un simple data.frame et que nous voulions calculer la somme groupe de la variable value
, lorsque regroupé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 lorsque nous essayons d'utiliser ce que nous pensons générer une somme groupée de dplyr
, 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
Cela ne nous donne pas la réponse souhaitée. Probablement à cause d'une interaction ou d'une surcharge du group_by
et ou mutate
fonctions entre dplyr
et plyr
. Nous pourrions détacher plyr
, mais vous pouvez également appeler les versions dplyr
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
nous voyons maintenant que cela fonctionne comme prévu.
dplyr fonctionne comme prévu dans votre exemple. Mutate, comme vous l'avez spécifié, ajoutera simplement 5 à chaque valeur de newvar lors de la création de newvar2. Cela ressemblerait si vous groupiez ou non. Si, toutefois, vous spécifiez quelque chose qui diffère d'un groupe à l'autre, vous obtiendrez quelque chose de différent. Par exemple:
df1 %.%
group_by(cyl) %.%
mutate(
newvar2 = newvar + mean(cyl)
)