Comme je suis assez nouveau dans R, je ne sais pas quels sont les méthodes et les objets S3. J'ai trouvé qu'il existe des systèmes d'objets S3 et S4, et certains recommandent d'utiliser S3 sur S4 si possible (http://google-styleguide.googlecode.com/svn/trunk/google-r-style.html). Cependant, je ne connais pas la définition exacte des méthodes/objets S3.
La plupart des informations pertinentes peuvent être trouvées en consultant ?S3
Ou ?UseMethod
, Mais en résumé:
S3 fait référence à un schéma de répartition des méthodes. Si vous utilisez R depuis un certain temps, vous remarquerez qu'il existe des méthodes print
, predict
et summary
pour de nombreux types d'objets différents.
En S3, cela fonctionne par:
glm
a la classe glm
)print
), puis un point, puis le nom de classe (par exemple: print.glm
)print
) pour que cela fonctionne, mais si vous cherchez simplement à vous conformer aux noms de méthode existants, vous n'en avez pas besoin (voir l'aide I mentionné plus tôt si vous le faites).Aux yeux du spectateur, et en particulier de l'utilisateur de votre package d'ajustement de modèle funky nouvellement créé, il est beaucoup plus pratique de pouvoir taper predict(myfit, type="class")
que predict.mykindoffit(myfit, type="class")
.
Il y en a un peu plus, mais cela devrait vous aider à démarrer. Il y a quelques inconvénients à cette façon de répartir les méthodes basées sur un attribut (classe) d'objets (et les puristes C restent probablement éveillés la nuit en horreur), mais pour beaucoup de situations, cela fonctionne décemment. Avec la version actuelle de R, de nouvelles méthodes ont été implémentées (S4 et classes de référence), mais la plupart des gens utilisent encore (uniquement) S3.
Pour commencer avec S3, regardez le code de la fonction median
. Taper median
à l'invite de commande révèle qu'il a une ligne dans son corps, à savoir
UseMethod("median")
Cela signifie qu'il s'agit d'une méthode S3. En d'autres termes, vous pouvez avoir une fonction median
différente pour différentes classes S3. Pour répertorier toutes les méthodes médianes possibles, tapez
methods(median) #actually not that interesting.
Dans ce cas, il n'y a qu'une seule méthode, la valeur par défaut, qui est appelée pour n'importe quoi. Vous pouvez voir le code pour cela en tapant
median.default
Un exemple beaucoup plus intéressant est la fonction print
, qui a de nombreuses méthodes différentes.
methods(print) #very exciting
Notez que certaines des méthodes ont *
s à côté de leur nom. Cela signifie qu'ils sont cachés dans l'espace de noms de certains packages. Utilisez find
pour savoir dans quel package ils se trouvent. Par exemple
find("acf") #it's in the stats package
stats:::print.acf
De http://adv-r.had.co.nz/OO-essentials.html :
Les trois systèmes R OO diffèrent dans la façon dont les classes et les méthodes sont définies:
S3 implémente un style de programmation OO appelé fonction générique OO. Ceci est différent de la plupart des langages de programmation, comme Java, C++ et C #, qui implémentent la transmission OO de messages. Avec la transmission de messages, les messages (méthodes) sont envoyées aux objets et l'objet détermine la fonction à appeler. Généralement, cet objet a une apparence spéciale dans l'appel de méthode, apparaissant généralement avant le nom de la méthode/du message: par exemple canvas.drawRect ("blue"). S3 est différent. Bien que les calculs soient toujours effectués via des méthodes, un type spécial de fonction appelé fonction générique décide de la méthode à appeler, par exemple drawRect (canvas, "blue"). S3 est un système très informel. Il n'a pas de définition des classes.
S4 fonctionne de manière similaire à S3, mais est plus formel. Il y a deux différences majeures avec S3. S4 a des définitions de classe formelles, qui décrivent la représentation et l'héritage de chaque classe, et possède des fonctions d'aide spéciales pour définir les génériques et les méthodes. S4 a également une répartition multiple, ce qui signifie que les fonctions génériques peuvent choisir des méthodes basées sur la classe de n'importe quel nombre d'arguments, pas seulement un.
Les classes de référence, appelées RC pour faire court, sont très différentes de S3 et S4. RC implémente OO passant des messages, donc les méthodes appartiennent aux classes, pas aux fonctions. $ est utilisé pour séparer les objets et les méthodes, donc les appels de méthode ressemblent à canvas $ drawRect ("bleu"). Les objets RC sont également modifiables: ils n'utilisent pas la sémantique habituelle de copie sur modification de R, mais sont modifiés sur place. Cela les rend plus difficiles à raisonner, mais leur permet de résoudre des problèmes difficiles à résoudre avec S3 ou S4.
Il y a aussi un autre système qui n'est pas tout à fait OO, mais il est important de mentionner ici:
- les types de base, les types internes de niveau C qui sous-tendent les autres systèmes OO. Les types de base sont principalement manipulés à l'aide du code C, mais ils sont importants à connaître car ils fournissent les blocs de construction pour le autres systèmes OO.
Je suis venu à cette question en me demandant surtout d'où venaient les noms. Il ressort de cet article wikipedia que le nom fait référence à la version du langage de programmation S sur laquelle R est basé. Les schémas de répartition des méthodes décrits dans les autres réponses proviennent de S et sont étiquetés de manière appropriée en fonction de la version.
Essayer
methods(residuals)
qui répertorie, entre autres, "residuals.lm" et "residuals.glm". Cela signifie que lorsque vous avez ajusté un modèle linéaire, m et de type residuals(m)
, residuels.lm sera appelé. Lorsque vous avez ajusté un modèle linéaire généralisé, residuals.glm sera appelé. C'est une sorte de modèle d'objet C++ à l'envers. En C++, vous définissez une classe de base ayant des fonctions virtuelles, qui sont remplacées par des classes dérivées. Dans R, vous définissez une fonction virtuelle (alias générique), puis vous décidez quelles classes remplaceront cette fonction (alias définir une méthode). Notez que les classes faisant cela n'ont pas besoin d'être dérivées d'une super classe commune. Je ne serais pas d'accord pour préférer généralement S3 à S4. S4 a plus de formalisme (= plus de frappe) et cela peut être trop pour certaines applications. Les classes S4, cependant, peuvent être définies comme une classe ou une structure en C++. Vous pouvez spécifier qu'un objet d'une certaine classe est composé d'une chaîne et de deux nombres par exemple:
setClass("myClass", representation(label = "character", x = "numeric", y = "numeric"))
Les méthodes qui sont appelées avec un objet de cette classe peuvent s'appuyer sur l'objet ayant ces membres. C'est très différent des classes S3, qui ne sont qu'une liste d'un tas d'éléments.
Avec S3 et S4, vous appelez une fonction membre par fun(object, args)
et non par object$fun(args)
. Si vous cherchez quelque chose comme ce dernier, jetez un œil au package proto.