web-dev-qa-db-fra.com

Comment répliquer un comportement ddply qui utilise une fonction personnalisée avec dplyr?

J'essaie de remplacer tous mes appels plyr par dplyr. Il y a encore quelques accrocs et l'un d'eux est avec la fonction group_by. J'imagine qu'il agit de la même manière que le deuxième argument ddply et effectue une scission, une application et une combinaison en fonction des variables de regroupement répertoriées. Mais cela ne semble pas être le cas. Voici un exemple assez trivial.

Définissons une fonction idiote

mm <- function(x) return(x[1:5, ])

Maintenant, nous pouvons diviser les espèces dans le irisdataset comme ceci et appliquer cette fonction à chaque morceau.

ddply(iris, .(Species), mm)

Cela fonctionne comme prévu. Cependant, lorsque j'essaie la même chose avec dplyr, cela ne fonctionne pas comme prévu. 

iris %>% group_by(Species) %>% mm

Qu'est-ce que je fais mal?

34
Maiasaura

Comme indiqué dans ?do, vous pouvez faire référence à un groupe avec . dans votre expression. Les éléments suivants vont répliquer votre sortie ddply:

iris %>% group_by(Species) %>% do(.[1:5, ])

# Source: local data frame [15 x 5]
# Groups: Species
#
#    Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
# 1           5.1         3.5          1.4         0.2     setosa
# 2           4.9         3.0          1.4         0.2     setosa
# 3           4.7         3.2          1.3         0.2     setosa
# 4           4.6         3.1          1.5         0.2     setosa
# 5           5.0         3.6          1.4         0.2     setosa
# 6           7.0         3.2          4.7         1.4 versicolor
# 7           6.4         3.2          4.5         1.5 versicolor
# 8           6.9         3.1          4.9         1.5 versicolor
# 9           5.5         2.3          4.0         1.3 versicolor
# 10          6.5         2.8          4.6         1.5 versicolor
# 11          6.3         3.3          6.0         2.5  virginica
# 12          5.8         2.7          5.1         1.9  virginica
# 13          7.1         3.0          5.9         2.1  virginica
# 14          6.3         2.9          5.6         1.8  virginica
# 15          6.5         3.0          5.8         2.2  virginica

Plus généralement, pour appliquer une fonction personnalisée à des groupes avec dplyr, vous pouvez procéder comme suit (merci @docendodiscimus):

iris %>% group_by(Species) %>% do(mm(.))
35
jbaums

slice a été créé pour cela:


library(dplyr)
iris %>% group_by(Species) %>% slice(1:5)
#> # A tibble: 15 x 5
#> # Groups:   Species [3]
#>    Sepal.Length Sepal.Width Petal.Length Petal.Width Species   
#>           <dbl>       <dbl>        <dbl>       <dbl> <fct>     
#>  1          5.1         3.5          1.4         0.2 setosa    
#>  2          4.9         3            1.4         0.2 setosa    
#>  3          4.7         3.2          1.3         0.2 setosa    
#>  4          4.6         3.1          1.5         0.2 setosa    
#>  5          5           3.6          1.4         0.2 setosa    
#>  6          7           3.2          4.7         1.4 versicolor
#>  7          6.4         3.2          4.5         1.5 versicolor
#>  8          6.9         3.1          4.9         1.5 versicolor
#>  9          5.5         2.3          4           1.3 versicolor
#> 10          6.5         2.8          4.6         1.5 versicolor
#> 11          6.3         3.3          6           2.5 virginica 
#> 12          5.8         2.7          5.1         1.9 virginica 
#> 13          7.1         3            5.9         2.1 virginica 
#> 14          6.3         2.9          5.6         1.8 virginica 
#> 15          6.5         3            5.8         2.2 virginica
0
Moody_Mudskipper