web-dev-qa-db-fra.com

Apprendre à comprendre plyr, ddply

J'ai essayé de comprendre quoi et comment fonctionne plyr en essayant différentes variables et fonctions et en voyant quels résultats. Je recherche donc plus une explication du fonctionnement de plyr qu'un correctif spécifique auquel il répond. J'ai lu la documentation mais mon cerveau de débutant ne l'obtient toujours pas.

Quelques données et noms:

mydf<- data.frame(c("a","a","b","b","c","c"),c("e","e","e","e","e","e")
                  ,c(1,2,3,10,20,30),
                  c(5,10,20,20,15,10))
colnames(mydf)<-c("Model", "Class","Length", "Speed")
mydf

Question 1: synthèse par rapport à la syntaxe de transformation

Donc, si j'entre: ddply(mydf, .(Model), summarise, sum = Length+Length)

Je reçois:

`Model ..1
1     a   2
2     a   4
3     b   6
4     b  20
5     c  40
6     c  60

et si j'entre: ddply(mydf, .(Model), summarise, Length+Length) j'obtiens le même résultat.

Maintenant, si vous utilisez transform: ddply(mydf, .(Model), transform, sum = (Length+Length))

Je reçois:

  Model Class Length Speed sum
1     a     e      1     5   2
2     a     e      2    10   4
3     b     e      3    20   6
4     b     e     10    20  20
5     c     e     20    15  40
6     c     e     30    10  60

Mais si je le dis comme le premier résumé: ddply(mydf, .(Model), transform, (Length+Length))

  Model Class Length Speed
1     a     e      1     5
2     a     e      2    10
3     b     e      3    20
4     b     e     10    20
5     c     e     20    15
6     c     e     30    10

Alors pourquoi l'ajout de "sum =" fait-il une différence?

Question 2: Pourquoi cela ne fonctionne-t-il pas?

ddply(mydf, .(Model), sum, Length+Length) #Erreur dans la fonction (i): objet 'Longueur' introuvable

ddply(mydf, .(Model), length, mydf$Length) #Error in .fun(piece, ...) : 

2 arguments passés à "longueur" qui nécessite 1

Ces exemples sont plus pour montrer que quelque part je ne comprends pas fondamentalement comment utiliser plyr.

Toutes les réponses ou explications sont appréciées.

22
rsgmon

La syntaxe est la suivante:

ddply(data.frame, variable(s), function, optional arguments)

où la fonction devrait renvoyer un data.frame. Dans votre situation,

  • résumer est une fonction qui créera de manière transparente un nouveau data.frame, avec les résultats de l'expression que vous fournissez comme arguments supplémentaires (...)

  • transform, une fonction R de base, transformera les data.frames (d'abord divisées par la ou les variables), en ajoutant de nouvelles colonnes en fonction de l'expression ou des expressions que vous fournissez comme arguments supplémentaires. Ceux-ci doivent être nommés, c'est exactement ainsi que fonctionne la transformation.

Si vous utilisez d'autres fonctions que sous-ensemble, transformer, muter, avec, dans ou résumer, vous devrez vous assurer qu'elles renvoient un data.frame (la longueur et la somme ne le font pas), ou à tout le moins un vecteur approprié longueur pour la sortie.

19
baptiste

Je trouve que lorsque j'ai du mal à "visualiser" le fonctionnement de l'un des outils fonctionnels de R, la chose la plus simple à faire est de parcourir une seule instance:

ddply(mydf, .(Model), function(x) browser() )

Inspectez ensuite x en temps réel et tout devrait avoir du sens. Vous pouvez ensuite tester votre fonction sur x, et si cela fonctionne, vous êtes en or (sauf si les autres groupes sont différents de votre premier x).

22
Ari B. Friedman

La façon dont je comprends les opérations ddply(... , .(...) , summarise, ...) sont conçues pour réduire le nombre de lignes pour correspondre au nombre de combinaisons distinctes à l'intérieur des variables de regroupement .(...). Donc, pour votre premier exemple, cela semblait naturel:

ddply(mydf, .(Model), summarise, sL = sum(Length)
  Model sL
1     a  3
2     b 13
3     c 50

D'ACCORD. Semble fonctionner pour moi (pas un utilisateur régulier de plyr). D'un autre côté, les opérations transform, je comprends, créent de nouvelles colonnes de la même longueur que la trame de données. C'est ce qu'a accompli votre premier appel transform. Votre deuxième (un échec) était:

ddply(mydf, .(Model), transform, (Length+Length))

Celui-ci n'a pas créé de nouveau nom pour l'opération qui a été effectuée, il n'y a donc rien de nouveau attribué dans le résultat. Lorsque vous avez ajouté sum=(Length+Length), un nom était soudainement disponible (et la fonction sum était non utilisée). C'est généralement une mauvaise idée d'utiliser les noms de fonction pour les noms de colonne.

Sur la deuxième question, je pense que l'argument .fun doit être une fonction plyr ou quelque chose qui a du sens appliqué à une trame de données (fractionnée) dans son ensemble plutôt qu'une ancienne fonction. Il n'y a pas de fonction sum.data.frame. Mais "nrow" ou "ncol" a du sens. Vous pouvez même faire travailler "str" dans cette position. La fonction de longueur appliquée à une trame de données donne le nombre de colonnes:

 ddply(mydf, .(Model), length )  # all 4's
4
42-