Ecrire un tutorial S4 : collaboration !

Postez ici vos questions, réponses, commentaires ou suggestions - Les sujets seront ultérieurement répartis dans les archives par les modérateurs

Modérateur : Groupe des modérateurs

Christophe Genolini
Messages : 698
Enregistré le : 12 Juin 2006, 21:37
Contact :

Ecrire un tutorial S4 : collaboration !

Messagepar Christophe Genolini » 03 Fév 2008, 13:57

Bonjour

Je suis en train d'apprendre a me servir de S4. Comme toujours quand j'apprends, je me fais un petit résumé de ce que je découvre. Comme je suis 'S4 débutant', mon résumé n'est pas vraiment une fiche parce qu'il contient également des questions. Mais si un expert S4 y jette un coup d'oeil, ca peut devenir nettement plus sérieux.

L'idée est d'écrire un :
projet a écrit :S4 pour les nuls
(et les pas si nuls !)

Je me charge de l'essentiel de la rédaction, et toi, cher futur co-auteur, tu apportes des précisions techniques et des correctifs sur ce qui m'aurait échappé...

Ca tante quelqu'un ?

Christophe

Pierre Bady
Messages : 405
Enregistré le : 02 Mai 2006, 07:46

Messagepar Pierre Bady » 04 Fév 2008, 10:08

bonjour,

je trouve que c'est une bonne idée.

Par contre, j'ai pas beaucoup de temps :')
éventuellement, je pourrais jeter un coup d'oeil
(le regard du naif, étant une buse dans ce domaine :p
mais guère plus ... dsl :')


@++ et bonne continuation :)

Pierre
=@===--------¬-------¬------¬-----¬
liens utiles :
http://www.gnurou.org/Writing/SmartQuestionsFr
http://neogrifter.free.fr/welcomeOnInternet.jpg
]<((((*< -------------------------------

Christophe Genolini
Messages : 698
Enregistré le : 12 Juin 2006, 21:37
Contact :

Messagepar Christophe Genolini » 05 Fév 2008, 07:08

Dites les modo, y a un moyen de faire un post éditable/modifiable par plusieurs personne ?

Christophe Genolini
Messages : 698
Enregistré le : 12 Juin 2006, 21:37
Contact :

Messagepar Christophe Genolini » 05 Fév 2008, 07:14

V0.1 Introduction a écrit :
\title{S4 pour les (pas si) nul}
\author{Tutorial collectif} % Enfin, j'espère

\begin{document}


%**********************************
\section{Introduction}


\subsection{S4, c'est quoi ?}

S4 est la 4ieme version de S, S est la version payante de R. La particularité du S4 par rapport au S3 est l'apparition de fonctions qui permettent de considérer R comme un langage objet.
Par extension, S4 désigne donc la programmation orienté objet sous R.


\subsection{Pourquoi faire du S4 ?}

Pour le néophite, la programmation objet est quelque chose de lourd et les avantages ne semblent pas évidents. Pire, le S4 est même assez contraignant : il faut penser son programme à l'avance,
choisir ses types, penser aux liens qui lierons les objets entre eux... En pratique, la programmation objet "force" le programmeur à avoir une réflexion préliminaire.

De plus, les objets doivent être déclarés et typés. En bref, on peut moins faire de "cuisine à la va-vite", on est plus obligé de réfléchir.
Le bilan est un programme plus propre et donc moins buggué.

[[[ Aux connaisseurs S4 et Objets : d'autres raison de faire de l'objet ? ]]]
[[[ L'utilisateur n'a pas non plus a se soucier de la structure de donnée : peut lui importe que les champs soit des listes ou des matrices, il y accede de la meme manière]]]


\subsection{Qu'est ce que la programmation objet ?}

Un 'objet' est un ensemble de variables et de fonctions qui concernent toutes le même théme : l'objet lui-même. Par exemple, un objet 'image' contiendra les variables qui permettent de définir une
image (comme la taille de l'image, son mode de compression, l'image proprement dite) et les fonctions utilisées pour la manipulation de l'image (comme 'noirEtBlanc' ou 'redimentionnage').

Petit détail terminologique, les variables d'un objet sont appelées ``champ'', ses fonctions sont des ``méthodes''.


\subsection{Pourquoi faire simple (S2 et S3) quand on peut faire compliqué (S4) ?}

Quelques exemple montrant l'intérêt de l'objet.

Exemple : L'IMC, l'Indice de Masse Corporelle est une mesure de maigreur ou d'obésité. On le calcule en divisant le poids (en kilo) par la taille au carré. Ensuite, on conclut :
\begin{itemize}
\item 20 < IMC < 25 : tout roule pour vous
\item 25 < IMC < 30 : Nounours
\item 30 < IMC < 40 : Nounours confortable
\item 40 < IMC : Méga nounours, avec effet double douceur, mais qui devrait tout de même aller voir un médecin très vite...
\item 18 < IMC < 20 : Barbie
\item 16 < IMC < 18 : Barbie manequin
\item IMC < 16 : Barbie squelette, même diagnostic que le Méga nounours, attention danger...
\end{itemize}

On veut donc calculer l'IMC. En programmation classique, rien de plus simple :

Code : Tout sélectionner

Poids <- 85
Taille <- 1.84
( IMC <- Poids / Taille^2 )
[1] 25.10633


Jusqu'à la, rien de très mystérieux. Si vous voulez calculer pour deux personnes Moi et Elle, vous aurez

Code : Tout sélectionner

PoidsMoi <- 85
TailleMoi <- 1.84
IMCmoi <- PoidsMoi / TailleMoi^2 )
PoidsElle <- 62 # Et ouaips...
TailleElle <- 1.60
IMCelle <- PoidsElle / PoidsElle^2 )


Essayez, ca marche... mais c'est faux ! En effet, dernière ligne, il y a une erreur, j'ai divisé son poids par le mien.
Naturellement, R n'a rien vu, il a juste fait une multiplication entre deux numerics. Le pauvre, me direz-vous, comment pourrait-il 'voir' une erreure que l'humain lui-même laisse parfois passer ? Justement, la est le but de l'objet.

En langage objet, la démarche est tout autre. Il faut commancer par définir un objet "IMC". Cet objet IMC a deux champs, un champ "poids" et un "taille".
Ensuite, il faut définir une fonction "calculIMC". Le code équivalent au précédent est alors

Code : Tout sélectionner

monIMC <- NouvelObjet("IMC",Poids=85,Taille=1.84)
calculIMC(monIMC)
sonIMC <- NouvelObjet("IMC",Poids=62,Taille=1.60)
calculIMC(sonIMC)


Il n'y a plus d'erreur. La est toute la force de l'objet : la conception même du programme élimine d'office un certain nombre d'erreurs.

De même, l'objet protège des erreurs de typage :

Code : Tout sélectionner

Poid  <- `Bonjour'                                       # Aucun problème
NouvelObjet("IMC",poids='bonjour',taille=1.84)           # Problème
Erreur dans l'objet `IMC', 'taille' doit être numeric


On peut également construire des vérificateurs de cohérance, comme par exemple interdire des tailles négatives :

Code : Tout sélectionner

TailleMoi <- -1.84                                      # Aucun problème
NouvelObjet("IMC",poids=85,taille=-1.84)                # Problème
Erreur dans l'objet `IMC', 'taille' doit être positive

TailleElle <- 160                                       # Aucun problème
NouvelObjet("IMC",poids=85,taille=160)                # Problème
Erreur dans l'objet `IMC', 'taille' doit être entre 1.00 et 2.50


En bref, l'objet permet :

\begin{itemize}
\item une vision plus syntétique de ce que l'on fait
\item une programmation moins bugguée
\end{itemize}




François Bonnot
Messages : 537
Enregistré le : 10 Nov 2004, 15:19
Contact :

Messagepar François Bonnot » 05 Fév 2008, 13:50

Christophe Genolini a écrit :Dites les modo, y a un moyen de faire un post éditable/modifiable par plusieurs personne ?

A ma connaissance, l'outil de gestion de forum que nous utilisons (phpBB) ne le permet pas de façon simple, à moins (peut-être) de créer des groupes d'utilisateurs. Quand bien même il le pourrait techniquement, la gestion du forum (droits d'accès, etc) demanderait alors plus de temps que nous ne pouvons y consacrer. Dans sa configuration actuelle, un message peut seulement être édité par son auteur et les modérateurs.

FB

Christophe Genolini
Messages : 698
Enregistré le : 12 Juin 2006, 21:37
Contact :

Messagepar Christophe Genolini » 05 Fév 2008, 14:20

François Bonnot a écrit :demanderait alors plus de temps que nous ne pouvons y consacrer. Dans sa configuration actuelle, un message peut seulement être édité par son auteur et les modérateurs.


Ok

Christophe Genolini
Messages : 698
Enregistré le : 12 Juin 2006, 21:37
Contact :

Messagepar Christophe Genolini » 06 Fév 2008, 20:48

Exemple a écrit :\section{Exemple}

Plutôt que d'inventer un exemple farfelu avec des 'foo', des 'bar' et des 'taillesBidons', voila un cas réel (fortement simplifié, mais réel) :
la doctoresse (ou psychiatre, il faudra que je lui redemande) Tam travaille sur les anorexiques. Semaine après semaine, elle mesure leur IMC.
La suite de qu'elle obtient forme une 'trajectoire'.
Puis, elle classe ses patientes en groupe selon des critères bien précis ([AGrandi] Oui/Non, [DemandeAVoirSesParents] Oui/Non/Refuse, [RemangeRapidement] Oui/Non). Son but est de comparer des partitionnement de trajectoires ; les comparer après avoir calculer des indices statistiques, mais également graphiquement.



\subsection{Analyse du problème}

Le problème semble être découpable en trois objets.
\begin{itemize}
\item Le première sera celui qui contiendra les trajectoires des patientes.
\item Le deuxième sera une partition possible des patientes.
\item Le troisième sera un mélange des deux : les trajectoires partitionnées en groupe.
\end{itemize}



\subsection{L'objet 'trajectoires'}

\subsubsection{Champs}

Tam nous prévient que pour un groupe donné,
les mesures sont faites soit toutes les semaines, soit tous les quinze jours. L'objet trajectoire doit en tenir compte. Il sera donc défini par deux champs :
\begin{itemize}
\item 'temps' : le temps auquel les mesures sont effectuées.
\item 'traj' : les trajectoires de poids des patientes
\end{itemize}

Traj contiendra le tableau des trajectoires :

Code : Tout sélectionner

traj =
I1 15   15.1 15.2 15.2
I2 16   15.9 16   16.4
I3 15.2 15.2 15.3 15.3
I4 15.5 15.6 15.8 16

Temps contiendra les semaines ou les mesures ont été effectuées. Pour simplifier, on prend pour semaine 1 la semaine ou commence le suivit du groupe :

Code : Tout sélectionner

temps = 1 2 4 5


\subsubsection{Méthodes}

On distingue généralement 5 types d'opérations à faire sur les objets :
\begin{itemize}
\item Méthodes de création : généralement, la création d'un objet est une peu rugueuse pour l'utilisateur. Le programmeur écrit donc des méthodes 'sympa' pour créer un objet à partir d'un fichier ou a partir d'un autre objet (genre 'as').
\item Validation : en programmation objet, il est possible de vérifier que les champs respectent certaines contraintes. Il est également possible de créer certains champs à partir de calculs fait sur les autres champs. Tout cela rentre dans la validation d'objet.
\item Affichage : Créer c'est bien, voir c'est mieux ! Il est donc important de prévoir des méthodes pour afficher l'objet, numériquement autant que graphiquement ('print' et 'plot')
\item Manipulation des champs : modifier et lire les champs n'est pas aussi anodin que dans la programmation classique. Aussi, on dédie des méthodes à la manipulation des champs.
\item Autres : tout ce qui précède est le pack de base. Reste les méthodes spécifiques à l'objet, celles qui généralement ont justifier sa création...
\end{itemize}

[[[Découpage à refaire : pas de méthode pour chaque groupe puisqu'on a défini les méthodes de base]]]

\subsection{L'objet 'partition'}

\subsubsection{Champs}

Une partition est un ensemble de groupe. Par exemple les groupes pourraient être A ={I1,I3} et B={I2,I4}.
Il sera sans doute plus simple de les considérer comme une liste ayant pour longueur le nombre de patientes : partition = {A,B,A,B}.
Dans un certain nombre de cas, il faudra également connaitre le nombre de groupe, en particulier si un groupe est manquant : si Tam classe ses ado en trois groupes et qu'elle obtient la partition
{A,C,C,A}, il est important de garder en mémoire que le groupe B existe, même s'il n'est pas représenté. D'ou deux champs pour partition :
\begin{itemize}
\item 'nbGroupe' : donne le nombre de groupe.
\item 'part' : la suite des groupes auxquels les trajectoires appartiennent.
\end{itemize}

\subsubsection{Méthodes}

Les partitions seront sans doute assez rarement manipulées par l'utilisateur. Un affichage sera probablement suffisant.
\begin{itemize}
\item Affichage
\end{itemize}


\subsection{L'objet 'trajDecoupees'}

\subsubsection{Champs}

trajDecoupees sera l'objet regroupant trajectoires et partitionnement. Il est possible que pour un ensemble de trajectoire, plusieurs partitionnements soient intéressant. On doit donc
prévoir de regrouper un objet trajectoire et plusieurs objets partitions dans 'trajDecoupees' :
\begin{itemize}
\item 'temps' : le temps auquel les mesures sont effectuées (comme dans 'trajectoires')
\item 'traj' : les trajectoires de poids des patientes (comme dans 'trajectoires')
\item 'partitionS' : un ensemble de partition.
\end{itemize}

\subsubsection{Méthodes}

Clairement, la fabrication puis l'affichage de cet objet sera la finalité de notre travail. Pour le manipuler, il faut donc des procédures
d'affichage (les même que pour 'partitions' ? A voir...) Tam nous dit également qu'un partitionnement classique est de faire deux groupes, ceux dont l'IMC inital est au dessus de la moyenne, ceux dont l'IMC initial
est en dessous de la moyenne. Elle aura besoin de ce partitionnement en standard. Cela nous fait 5 méthodes en perspective :

\begin{itemize}
\item Représentation graphique
\item Affichage détaillé
\item Affichage cours
\item Résumé
\item PartionneInitial
\end{itemize}

\subsection{En bref}

Pour résumer, nous avons donc trois classes :

Code : Tout sélectionner

xxxxxxxxxxxxxxxxxxxxxxxxxx
x Class: traj            x
x------------------------x
x Champs:                x
x   - time               x
x   - traj               x
x------------------------x
x Methodes:              x
x   - plot               x
x   - print              x
x   - short.print        x
x   - summary            x
xxxxxxxxxxxxxxxxxxxxxxxxxx

xxxxxxxxxxxxxxxxxxxxxxxxxx
x Class: partition       x
x------------------------x
x Champs:                x
x   - nbCluster          x
x   - cluster            x
x------------------------x
x Methodes:              x
x   - print              x
xxxxxxxxxxxxxxxxxxxxxxxxxx

xxxxxxxxxxxxxxxxxxxxxxxxxx
x Class: partition       x
x------------------------x
x Champs:                x
x   - time               x
x   - traj               x
x   - nbCluster          x
x   - cluster            x
x------------------------x
x Methodes:              x
x   - plot               x
x   - print              x
x   - short.print        x
x   - summary            x
x   - partitionneMoy     x
xxxxxxxxxxxxxxxxxxxxxxxxxx


Et R dans tout ca, me direz-vous ? C'est également une des caractéristiques des langages objets,
nous avons fait une analyse relativement poussée (poussée pour un
problème aussi simple que le notre) et il n'y a toujours pas la
moindre ligne de code R... Théoriquement, on pourrait même choisir de coder dans un autre langage.
Mais bon, la n'est pas le sujet du jour.

Christophe Genolini
Messages : 698
Enregistré le : 12 Juin 2006, 21:37
Contact :

Messagepar Christophe Genolini » 07 Fév 2008, 08:05

\section{Déclaration des classes}

Dans la majorité des langages objets, la définition de l'objet contient les champs et les méthodes.
En R, la définition ne contient que les champs. Les méthodes sont précisées ensuite.


\subsection{Les champs}


La premiere étape est donc de définir les champs de l'objet proprement dit.
Cela se fait à l'aide de l'instruction 'setClass'. setClass est une fonction qui
prend comme argument le nom de la classe, la liste des champs et
quelques autres broutilles, que nous verrons plus tard. Le nom de l'objet est
donnée par 'Class' et les champs sont données sous forme de liste par
'representation'.

Comme nous l'avons vu dans l'exemple introductif, la programmation objet fait du contrôle de type, c'est à dire qu'elle ne permettra pas
à une chaine de caracters d'être ranger la ou devrait se trouver en entier.
Chaque champ doit être déclaré avec son type.


Code : Tout sélectionner

setClass(
 Class="trajectoires",
 representation=list(
   temps = 'numeric',
   traj = 'matrix'
 )
)



[[[2. Question aux connaisseurs S4 : on peut soit utiliser "representation=list(temps = 'numeric',traj = 'matrix')" soit "representation(temps = 'numeric',traj = 'matrix')". Cela fait-il une différence ?]]]



On peut ensuite créer un objet 'trajectoire' grace à new :

Code : Tout sélectionner

new("trajectoires")


Comme vous pouvez le constater, l'affichage n'est pas terrible. Il
sera important de définir une méthode pour arranger ca.

Naturellement, un objet se stocke dans une variable comme n'importe
quelle autre valeur de R.

Code : Tout sélectionner

trajCochin <- new("trajectoires")


On peut ensuite acceder aux champs de trajCochin grace à l'opérateur @ :

Code : Tout sélectionner

trajCochin@temps
[1] numeric(0)
trajCochin@temps <- 3 
trajCochin
An object of class "trajectoires"
Slot "temps":
[1] 3

Slot "traj":
<0 x 0 matrix>


\paragraph{Attention} : comme nous le verrons par la suite, l'opérateur '@' est à utiliser avec parcimonie. En fait, il ne devrait jamais être utiliser sauf dans les méthodes.
L'utilisation que nous présentons ici (affichage d'un champ, et pire encore affectation d'une valeur à un champ) est à proscrire.

Par contre, on peut créer un objet en lui donnant directement les valeurs qu'il doit affecter à ses champs :

Code : Tout sélectionner

traj1 <- matrix(c(1,2,3,2,1,4),nrow=2)
trajStAnne <- new("trajectoires",temps=c(1,23),traj=traj1)


Enfin, on aurait pu déclarer un objet en lui donnant des valeurs par défaut. A chaque création, si l'utilisateur ne spécifie pas les valeurs des champs, ceux-ci en auront quand même une.
On fait cela grace à 'prototype'

Code : Tout sélectionner

setClass(
  Class="trajectoiresBis",
  representation=list(
    temps = 'numeric',
    traj = 'matrix'
  ),
  prototype=list(
    temps = 1,
    traj = matrix(0)
  )
)


Dans le cas précis de l'objet 'trajectoires', il n'y a pas vraiment de valeur par défaut qui s'impose.
Il est donc préférable de conserver la classe comme elle a été initialement définie.

Voila, nous avons défini notre premier objet. Par contre, j'espère que vous êtes plus adroit que moi :
dans la définition de trajStAnne, j'ai fait une petite erreure de typo, j'ai tapé '1,23' au lieu de '1,2,3'.
Du coup, il y a moins de 'temps' qu'il n'y a de colonne dans 'traj' et notre objet est incohérant.
Naturellement, R n'a rien vu. Mais il est possible de l'éduquer...



\subsection{Généralitées sur les méthodes}

Les méthodes sont définies grâce à la fonction 'setMethod'. Cette fonction prend pour premier argument le nom de la méthode qui est en train d'être définie, comme second le nom
de l'objet et comme troisième la fonction à exécuter quand cette méthode est appelée. Par exemple

Code : Tout sélectionner

setMethod("print",
  "trajectoires",
  function(x,...){cat("*** Voila des trajectoires mesurées aux temps ",x@temps," ***\n")}
)
printPourTrajectoire(trajStAnne)


On distingue trois types méthodes : celles directement liées à la programmation objet (comme par exemple les constructeurs, que nous verons bientot),
celles qui viennent imiter des fonctions déja existantes (comme 'print' pour l'objet 'trajectoire') et celles totalement nouvelles inventées par l'utilisateur.


\subsection{Méthodes liées à la programmation objet}

Ces méthodes permettent de faire certainnes vérifications sur les objets, de les contrôler, de manipuler leur structure.


\subsubsection{Vérificateur}

Le vérificateur est là pour contrôler qu'il n'y a pas d'incohérance interne dans l'objet. On lui donne des règles, et à chaque création d'objet, il vérifiera que l'objet suit les règles.

Dans le cas de l'objet trajectoire,
il doit y avoir autant de colonnes dans la matrice 'traj' que dans 'temps'. Nous allons donc demander au vérificateur de s'en assurer. Le vérificateur est une méthode un peu part.
Il n'est pas défini avec 'setMethod' mais avec 'setValidity' a qui nous donnons le nom de l'objet,
puis une fonction de vérification. La fonction de vérification prend comme argument l'objet, et retourne soit TRUE, soit une erreure :

Code : Tout sélectionner

setValidity("trajectoire",
  method=function(object){
    if(length(object@temps)!=ncol(object@traj)){
      stop("[trajectoire:validation] Le nombre de mesures temporelles ne correspond pas au nombre de colonnes de la matrice")
    }else{
      return(TRUE)
    }
  }
)


Si nous essayions maintenant de definir trajStAnne comme nous l'avions fait précédement, le vérificateur nous en empècherait :

Code : Tout sélectionner

trajStAnne <- new("trajectoire",temps=c(1,23),traj=traj1)
Erreur dans validityMethod(object) :
  aucun slot de nom "temps" pour cet objet de la classe "maclasse"
trajStAnne <- new("trajectoire",temps=c(1,2,3),traj=traj1)


Au passage, une remarque générale : quand vous faites un programme long avec de nombreux objets et de nombreuses fonctions, il est toujours difficile, en cas d'erreur, de savoir
quelle fonction vient de stoper. [[[4. Peut-être parce que je ne maitrise pas les outils de débugage ?]]] Donner un message d'erreur précis qui indique le nom de l'objet
et la méthode incriminée aide grandement.

\paragraph{Attention :} le vérificateur n'est appellé QUE lors de la création initiale de l'objet. Si ensuite il est modifié, rien ne va plus, il n'y a plus de contrôle :

Code : Tout sélectionner

trajStLouis <- new("trajectoire",temps=c(1),traj=matrix(1))
trajStLouis@temps <- c(1,23)


Voila une des raisons qui poussent à proscrire l'utilisation de '@' pour modifier les valeurs des champs.
[[[5. Question aux connaisseurs S4 : est-il possible de créer un vérificateur qui contrôle également les modifications a pas seulement la création ?]]]

\subsubsection{Constructeur}

Le vérificateur est une version simplifié d'un outil bien plus puissant appelé le constructeur. Le constructeur est une méthode permettant de fabriquer un objet. Il est appelé à chaque utilisation
de la fonction 'new'.

Reprenons nos trajectoires. Il serait assez plaisant que les colonnes de la matrice des trajectoires aient des noms, les noms des temps où les mesures ont été prises. De même, les lignes
pourraient être indicées par un numero d'individu :

Code : Tout sélectionner

     T0    T1    T4    T5
I1  15    15.1  15.2  15.2
I2  16    15.9  16    16.4
I3  15.2  15.2  15.3  15.3
I4  15.5  15.6  15.8  16


Le constructeur va nous permettre de faire tout ca. Le constructeur est une methode qui, lors de l'appel de 'new', fabrique l'objet tel que nous le voulons.
Le nom de la méthode constructeur dans R est 'initialize'. 'initialize' fait appel à une fonction qui prend pour argument '.Objet',
l'objet qui est train d'être construit et les différentes valeur a affecter aux champs de l'objet.
Cette fonction doit se terminer par l'affectation des valeurs aux champs de .Object puis par un 'return(.Object)' :

Code : Tout sélectionner

setMethod("initialize",
  "trajectoire",
  function(.Object,temps,traj){
    colnames(traj) <- paste("T",temps,sep="")
    rownames(traj) <- paste("I",1:nrow(traj),sep="")
    .Object@temps <- temps
    .Object@traj <- traj
    return(.Object)
  }
)
new("trajectoire",temps=c(1,2,4,8),traj=matrix(1:8,nrow=2))


A noter que si un constructeur est défini, le vérificateur est désactivé. Dans notre cas, si 'temps' comporte moins de valeurs que de colonne dans traj,
le constructeur buggue. Si 'temps' comporte moins de valeurs que de colonne dans traj et que notre constructeur ne buggait pas
(par exemple si on commentait la ligne 'colnames(traj) <- paste("T",temps,sep="")', le vérificateur ne serait tout de même pas appelé.

[[[6. Question aux connaisseurs S4 : Du coup, le vérificateur présente-t-il un intéret ?]]]

Si on décide d'utiliser un constructeur, il faut donc y inclure les vérifications. Notre constructeur, fusionné avec le vérificateur, devient :


Code : Tout sélectionner

setMethod("initialize",
  "trajectoire",
  function(.Object,temps,traj){
    if(length(object@temps)!=ncol(object@traj)){
      stop("[trajectoire:initialisation] Le nombre de mesures temporelles ne correspond pas au nombre de colonnes de la matrice")
    }else{
      colnames(traj) <- paste("T",temps,sep="")
      rownames(traj) <- paste("I",1:nrow(traj),sep="")
      .Object@temps <- temps
      .Object@traj <- traj
      return(.Object)
    }
  }
)
new("trajectoire",temps=c(1,2,4,8),traj=matrix(1:8,nrow=2))





A noter qu'un constructeur ne prend pas nécessaire pour argument les champs de l'objet. Par exemple, si on sait (ca n'est pas le cas dans la réalité, mais imaginons) que l'IMC
augmente de 0.1 toutes les semaines, on pourrait construire des trajectoires en fournissant le nombre de semaine et les poids initiaux :

Code : Tout sélectionner

setMethod("initialize",
  "trajectoire",
  function(.Object,nbSemaine,IMCinit){
    traj <- outer(IMCinit,1:nbSemaine,function(init,nbSem){return(init+0.1*nbSem)})
    colnames(traj) <- paste("T",1:nbSemaine,sep="")
    rownames(traj) <- paste("I",1:nrow(traj),sep="")
    .Object@temps <- 1:nbSemaine
    .Object@traj <- traj
    return(.Object)
  }
)
new("trajectoire",nbSemaine=4,IMCinit=c(16,17,15.6))


A noter que cette nouvelle définition a supprimer l'ancienne.


[[[7. Question aux connaisseurs S4 : est-il possible de définir plusieurs constructeur, en fonction des arguments qu'on leur donne ?]]]

Pierre Bady
Messages : 405
Enregistré le : 02 Mai 2006, 07:46

Messagepar Pierre Bady » 07 Fév 2008, 11:21

bonjour,

lol... j'ai pas le temps de suivre :D
En plus, je vais devoir retourner à mes cours de POO... :')

Par contre, est-ce qu'il ne serait pas plus pratique de faire un premier doc (tex/pdf ?) et de le proposer en lecture ?
la lecture des différents posts n'est pas très facile :')

Une section reference bibliographique pourrait être sympa.

@+++

pierre


PS: mdr pour les mega nounours :p
=@===--------¬-------¬------¬-----¬

liens utiles :

http://www.gnurou.org/Writing/SmartQuestionsFr

http://neogrifter.free.fr/welcomeOnInternet.jpg

]<((((*< -------------------------------

Franck Arnaud
Messages : 10
Enregistré le : 07 Jan 2008, 09:52
Contact :

Messagepar Franck Arnaud » 07 Fév 2008, 13:40

Bonjour à tous,

je pense effectivement que ça peut intéresser beaucoup de monde.

Dans la structure, je commencerai par parler de S3 pour 2 raisons : 1) pédago 2) de nombreuses fonctions sont encore S3-génériques (summary et length, par exemple)

Se pose aussi la question de l'organisation de la chose ? A la limite (mais je n'y connais rien), un wiki ?

Christophe Genolini
Messages : 698
Enregistré le : 12 Juin 2006, 21:37
Contact :

Messagepar Christophe Genolini » 07 Fév 2008, 14:40

Franck Arnaud a écrit :Bonjour à tous,
Dans la structure, je commencerai par parler de S3 pour 2 raisons : 1) pédago 2) de nombreuses fonctions sont encore S3-génériques (summary et length, par exemple)


Je n'y connais pas grand chose en S3. Mais si tu veux reprendre le même exemple et la meme structure que ce que je fais en S4, ca peut etre sympa. On changera le titre en "S3 et S4 pour les (pas si) nuls"...

Se pose aussi la question de l'organisation de la chose ? A la limite (mais je n'y connais rien), un wiki ?

Pour l'instant, on va faire simple : quelques bonnes volontés pour écrire, des débuttants qui essaient de s'y mettre et qui poseront des questions, des experts S4 qui je l'espère trouverons le temps de répondre aux questions que les auteurs posent.

Ca devrait faire un bon début.

Christophe

Nicolas Péru
Messages : 1408
Enregistré le : 07 Aoû 2006, 08:13

Messagepar Nicolas Péru » 07 Fév 2008, 17:27

Citation:

Se pose aussi la question de l'organisation de la chose ? A la limite (mais je n'y connais rien), un wiki ?


Pour l'instant, on va faire simple : quelques bonnes volontés pour écrire, des débuttants qui essaient de s'y mettre et qui poseront des questions, des experts S4 qui je l'espère trouverons le temps de répondre aux questions que les auteurs posent.

Ca devrait faire un bon début.

Christophe


D'autant plus qu'un wiki R existe déjà...ça ferait un peu double emploi même s'il est en anglais :). La traduction de ce tutorial pourrait être un objectif à terme avec la participation sur le wiki R ;)

Christophe Genolini
Messages : 698
Enregistré le : 12 Juin 2006, 21:37
Contact :

Messagepar Christophe Genolini » 22 Fév 2008, 19:21

Pierre Bady a écrit :bonjour,
Par contre, est-ce qu'il ne serait pas plus pratique de faire un premier doc (tex/pdf ?) et de le proposer en lecture ?
la lecture des différents posts n'est pas très facile :')


C'est fait : tutorial S4

Tous les commentaires sont les bienvenus...

Christophe
(447)

Christophe Genolini
Messages : 698
Enregistré le : 12 Juin 2006, 21:37
Contact :

Messagepar Christophe Genolini » 18 Mar 2008, 23:43

Une nouvelle version est disponible. Ça intéresse quelqu'un ?
(727)

Olivier Delaigue
Messages : 220
Enregistré le : 05 Déc 2006, 07:38

Messagepar Olivier Delaigue » 19 Mar 2008, 07:09

Ah ben c'est jamais complètement inintéressant ;-)


Retourner vers « Questions en cours »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité