Vous êtes sur la page 1sur 100

Petit Manuel de S4

Programmation Orient Objet sous R e

Christophe Genolini

Quallez-vous trouver dans ce manuel ?


Ce livre est un guide ` la programmation objet sous R (ou S4). Il ne ncessite pas de a e conna la programmation oriente objet. Par contre, un minimum de connaissances sur tre e R et sur la programmation en gnral est requis. Pour ceux qui sont totalement dbutants e e e en R, nous vous recommandons R pour les Dbutants, dEmmanuel Paradis [4]. e Le prsent manuel est dcoup en quatre parties. Apr`s une introduction gnrale e e e e e e sur la programmation objet (section 1) et une dnition un peu plus formelle (section 2), e un exemple est prsent (section 3). Grave probl`me que celui du choix de lexemple : e e e les exemples rels sont trop compliqus. Les articiels sont inintressants. Nous allons e e e donc utiliser une simplication dun probl`me rel ayant donn lieu ` la construction e e e a dun package (package kml). Il nous accompagnera tout au long de ce livre pour nir sous forme dun package appel miniKml disponible sur le site du CRAN. e La deuxi`me partie prsente les bases de la programmation objet. Chaque lment e e ee nouvellement introduit est ajout aux prcdents et permet au package de prendre corps. e e e Cest l` que sont prsents les lments fondamentaux de la programmation S4. Cette a e e ee partie est simple, rdige pour les dbutants, mais indispensable pour comprendre la e e e programmation objet en S. Les sections 4, 5, 6, 7 doivent se lire prfrentiellement dans ee lordre. Dans la troisi`me partie sont abords des sujets plus subtils, comme les signatures e e complexes (section 8), lhritable (section 9) ou la super assignation pour modication e interne dun objet (section 10). Elles ne sont pas indispensables ` la programmation a objet, on peut lire lune sans lautre et surtout les omettre en premi`re lecture. Cela e dpend ensuite des besoins de chacun. e En esprant que ce livre fera naitre de nombreux package S4, e bonne lecture !

Table des mati`res e


I Prliminaires e
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

9
11 11 11 11 12 13 15 15 16 16 16 17 19 19 19 19 20 21 22 22 23 23 24 25

1 Introduction 1.1 Quest-ce que S4? . . . . . . . . . . . . . . . . . . . . 1.2 Quest-ce que la programmation objet ? . . . . . . . . . 1.3 Pourquoi faire de lobjet ? . . . . . . . . . . . . . . . . . 1.3.1 Programmation classique . . . . . . . . . . . . . 1.3.2 Programmation objet . . . . . . . . . . . . . . . 1.4 Pour rsumer . . . . . . . . . . . . . . . . . . . . . . . . e 1.5 Devez-vous vous mettre ` lobjet ? . . . . . . . . . . . . a 1.6 Le ct obscur de la programmation . . . . . . . . . . . oe 1.6.1 Daccord, pas daccord . . . . . . . . . . . . . . . 1.6.2 Les fuses, la bourse, les bugs... et les coupables ! e 1.6.3 R, langage propre ? . . . . . . . . . . . . . . . . . 2 Gnralits sur les objets e e e 2.1 Dnition formelle . . . e 2.1.1 Les attributs . . 2.1.2 Les mthodes . . e 2.2 Dessiner, cest gagner ! . 3 Exemple de travail 3.1 Analyse du probl`me . . e 3.2 Lobjet Trajectoires . 3.3 Lobjet Partition . . . 3.4 Lobjet TrajDecoupees 3.5 Plan danalyse . . . . . 3.6 Application ` R . . . . . a

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

II

Les bases de lobjet

27
29 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 5

4 Dclaration des classes e 4.1 Dnition des attributs e

6 4.2 4.3 4.4 4.5 4.6 4.7 5 Les 5.1 5.2 5.3 Constructeur par dfaut e Accder aux attributs . e Valeurs par dfaut . . . e Supprimer un objet . . . Lobjet vide . . . . . . . Voir lobjet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

` TABLE DES MATIERES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 31 32 32 33 34 35 35 37 39 39 40 40 41 41 43 43 45 48 50 53 53 55 56 58

mthodes e setMethod . . . . . . . . . . . . . . show et print . . . . . . . . . . . . setGeneric . . . . . . . . . . . . . 5.3.1 Gnrique versus Spcique e e e 5.3.2 Dnition formelle . . . . . e 5.3.3 lockBinding . . . . . . . . 5.3.4 Dclaration des gnriques . e e e 5.4 Voir les mthodes . . . . . . . . . . e

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

6 Construction 6.1 Vricateur . . . . e 6.2 Linitiateur . . . . 6.3 Constructeur grand 6.4 Petit bilan . . . . . 7 Accesseur 7.1 Les getteurs . . . . 7.2 Les setteurs . . . . 7.3 Les oprateurs [ et e 7.4 [, @ ou get ? . . . .

. . . . . . . . public . . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . . . . [<. . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

III

Pour aller plus loin


. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

59
63 63 64 67 68 68 69 69 70 70 71

8 Mthodes utilisant plusieurs arguments e 8.1 Le probl`me . . . . . . . . . . . . . . . . e 8.2 signature . . . . . . . . . . . . . . . . . 8.3 missing . . . . . . . . . . . . . . . . . . 8.4 Nombre darguments dune signature . . 8.5 ANY . . . . . . . . . . . . . . . . . . . . . 9 Hritage e 9.1 Principe . . . . . . 9.2 P`re, grand-p`re et e e 9.3 contains . . . . . 9.4 unclass . . . . . .

. . . ANY . . . . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

` TABLE DES MATIERES 9.5 9.6 9.7 9.8 9.9 9.10 9.11 Arbre dhritage . . . . . . . e Voir la mthode en autorisant e callNextMethod . . . . . . . is, as et as<- . . . . . . . . . setIs . . . . . . . . . . . . . Les classes virtuelles . . . . . Pour les dyslexiques... . . . . . . . . . . lhritage e . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

7 72 72 75 77 78 80 82

10 Modication interne dun objet 83 10.1 Fonctionnement interne de R : les environnements . . . . . . . . . . . . . 83 10.2 Mthode pour modier un attribut . . . . . . . . . . . . . . . . . . . . . . 84 e

IV

Annexes

87

A Remerciements 89 A.1 Nous vivons une poque formidable . . . . . . . . . . . . . . . . . . . . . . 89 e A.2 Ceux par qui ce tutorial existe... . . . . . . . . . . . . . . . . . . . . . . . 89 B Mmo e B.1 Cration . . . . . . . . . . . . . . . e B.2 Validation . . . . . . . . . . . . . . B.3 Accesseur . . . . . . . . . . . . . . B.4 Mthodes . . . . . . . . . . . . . . e B.5 Quelques fonctions incontournables B.6 Voir la structure des objets . . . . C Pour aller plus loin Liste des tables et gures Bibliographie Index 91 91 91 92 92 92 92 95 96 97 98

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

` TABLE DES MATIERES

Premi`re partie e

Prliminaires e

Chapitre 1

Introduction
1.1 Quest-ce que S4?

S4 est la quatri`me version de S. S est un langage qui a deux implmentations : e e S-plus est commerciale, R est gratuite. La particularit de S4 par rapport au S3 est e lapparition de fonctions qui permettent de considrer S-plus comme un langage objet 1 . e Par extension, S4 dsigne la programmation oriente objet sous S. Et donc sous R et e e sous S-plus.

1.2

Quest-ce que la programmation objet ?

Un objet est un ensemble de variables et de fonctions qui concernent toutes le mme e th`me : lobjet lui-mme. Pas tr`s clair ? Prenons un exemple : un objet image contiene e e dra : Les variables qui permettent de dnir une image (comme la taille de limage, son e mode de compression, limage proprement dite) ; les fonctions utilises pour la manipulation de limage (comme noirEtBlanc() ou e redimentionner()). Si vous tes compl`tement dbutant en objet et que tout ca nest pas limpide, ne e e e vous inquitez pas, de nombreux exemples vont suivre. e

1.3

Pourquoi faire de lobjet ?

Pour le nophyte, la programmation objet est quelque chose de lourd et les avantages e ne semblent pas vidents : il faut penser son programme ` lavance, modliser le probl`me, e a e e choisir ses types, penser aux liens qui lieront les objets entre eux... Que des inconvnients. e Do` la question lgitime : pourquoi faire de lobjet ? u e
1. permettent de considrer et non pas transforment en. En tout tat de cause, R Nest PAS un e e langage objet, il reste un langage interprt classique avec une surcouche possible. A quand R++ ? ee

11

12

CHAPITRE 1. INTRODUCTION

1.3.1

Programmation classique

Le plus simple est de prendre un exemple et de comparer la programmation classique ` a la programmation objet. LIMC, lIndice de Masse Corporelle est une mesure de maigreur ou dobsit. On le calcule en divisant le poids (en kilo) par la taille au carr. Ensuite, e e e on conclut : 20 < IMC < 25 : tout roule pour vous 25 < IMC < 30 : Nounours 30 < IMC < 40 : Nounours confortable 40 < IMC : Mga nounours, avec eet double douceur, mais qui devrait tout de e mme aller voir un mdecin tr`s vite... e e e 18 < IMC < 20 : Barbie 16 < IMC < 18 : Barbie mannequin IMC < 16 : Barbie squelette, mme diagnostic que le Mga nounours, attention e e danger... On veut donc calculer lIMC. En programmation classique, rien de plus simple :
> > > > # ## Programmation classique , IMC poids <- 85 taille <- 1.84 ( IMC <- poids / taille ^2)

[1] 25.10633

Jusqu` l`, rien de tr`s mystrieux. Si vous voulez calculer pour deux personnes Moi a a e e et Elle, vous aurez
> > > > # ## Programmation classique , mon IMC poidsMoi <- 85 tailleMoi <- 1.84 ( IMCmoi <- poidsMoi / tailleMoi ^2)

[1] 25.10633

> > > >

# ## Programmation classique , son IMC poidsElle <- 62 tailleElle <- 1.60 ( IMCelle <- poidsMoi / tailleElle ^2)

[1] 33.20312

Ca marche... sauf quElle est qualie de Nounours confortable (ou Nounoursette e dans son cas) alors que son poids ne parait pas spcialement excessif. Un petit coup doeil e au code rv`le assez vite une erreur : le calcul de IMCelle est faux, nous avons divis e e e poidsMoi par tailleElle au lieu de poidsElle par tailleElle. Naturellement, R na pas dtect derreur : de son point de vue, il a juste eectu une division entre deux e e e numeric.

1.3. POURQUOI FAIRE DE LOBJET ?

13

1.3.2

Programmation objet

. En langage objet, la dmarche est tout autre. Il faut commencer par dnir un objet e e IMC qui contiendra deux valeurs, poids et taille. Ensuite, il faut dnir la fonction e print qui achera lIMC 2
> # ## D finition d ' un objet IMC e > setClass ( " IMC " , representation ( poids = " numeric " , taille = " numeric " )) [1] " IMC " > setMethod( " show " ," IMC " , + function ( object ){ + cat ( " IMC = " , object@poids / ( object@taille ^2) , " \ n " ) + } + ) [1] " show "

Le code quivalent ` ce qui a t fait dans la section 1.3.1 page 12 est alors : e a ee
> # ## Cr ation d ' un objet pour moi , et affichage de mon IMC e > ( monIMC <- new( " IMC " , poids =85 , taille =1.84)) IMC = 25.10633 > # ## Cr ation d ' un objet pour elle , et affichage de son IMC e > ( sonIMC <- new( " IMC " , poids =62 , taille =1.60)) IMC = 24.21875

A partir du moment o` linitialisation est correcte (probl`me qui se posait galement u e e dans la programmation classique), il ny a plus derreur possible. L` est toute la force a de lobjet : la conception mme du programme interdit un certain nombre de bug. e Typage : lobjet prot`ge galement des erreurs de typage, cest ` dire les erreurs qui e e a consistent ` utiliser un type l` o` il faudrait en utiliser un autre. Une erreur de typage, a a u cest un peu comme additionner des pommes et des kilom`tres au lieu dadditionner des e pommes et des pommes. Concr`tement, une variable nomme poids est conue pour contenir un poids, cest e e c a ` dire un nombre, et non une cha de caract`res. En programmation classique (pas de ne e typage), poids peut contenir nimporte quoi :
> # ## Programmation classique , pas de typage > ( poids <- " Bonjour " ) [1] " Bonjour " 2. Pour que notre exemple illustratif soit reproductible immdiatement, nous avons besoin de dnir e e ici un objet. Nous le faisons sans explication, mais naturellement, tout cela sera repris ensuite avec moults dtails. e

14

CHAPITRE 1. INTRODUCTION

En programmation objet, aecter "bonjour" ` une variable qui devrait contenir un a nombre provoquera une erreur :
> new( " IMC " , poids = " Bonjour " , taille =1.84) Error in validObject (. Object ) : invalid class " IMC " object : invalid object for slot " poids " in class " IMC " : got class " character " , should be or extend class " numeric "

Vricateurs : Lobjet permet de construire des vricateurs de cohrence pour, par e e e exemple, interdire certaines valeurs. En programmation classique, une taille peut tre e ngative : e
> # ## Programmation classique , pas de contr^ le o > ( TailleMoi <- -1.84) [1] -1.84

En programmation objet, on peut prciser que les tailles ngatives nexistent pas : e e
> # ## Programmation objet , contr^ le o > s e t V a l i d i t y ( " IMC " , + function ( object ){ + i f ( object@taille <0){ + return ( " Taille n gative " ) e + } else { + return (TRUE) + } + } + ) Class " IMC " [ in " . GlobalEnv " ] Slots : Name : poids taille Class : numeric numeric > new( " IMC " , poids =85 , taille = -1.84) Error in validObject (. Object ) : invalid class " IMC " object : Taille n gative e

Hritage : la programmation objet permet de dnir un objet comme hritier des e e e proprits dun autre objet, devenant ainsi son ls. Lobjet ls bncie ainsi de tout ee e e ce qui existe pour lobjet . Par exemple, on souhaite aner un peu nos diagnostics en fonction du sexe de la personne. Nous allons donc dnir un nouvel objet, IMCplus, qui e contiendra trois valeurs : poids, taille et sexe. Les deux premi`res variables sont les e

1.4. POUR RESUMER

15

mmes que celle de lobjet IMC. Nous allons donc dnir lobjet IMCplus comme hritier e e e de lobjet IMC. Il pourra ainsi bncier de la fonction show telle que nous lavons dnie e e e pour IMC et cela, sans aucun travail supplmentaire, puisque IMCplus hrite de IMC : e e
> # ## D finition de l ' h ritier e e > setClass ( " IMCplus " , + representation ( sexe = " character " ) , + contains = " IMC " + ) [1] " IMCplus " > > > > # ## Cr ation d ' un objet e lui <- new( " IMCplus " , taille =1.76 , poids =84 , sexe = " Homme " ) # ## Affichage qui utilise ce qui a t d fini pour IMC ' e e e lui

IMC = 27.11777

La puissance de cette caractristique apparaitra plus clairement section 9 page 69. e Encapsulation : enn, la programmation objet permet de dnir tous les outils e composant un objet et de les enfermer dans une boite, puis de ne plus avoir ` sen occuper. a Cela sappelle lencapsulation. Les voitures fournissent un bon exemple dencapsulation : une fois le capot referm, on na plus besoin de conna les dtails de la mcanique pour e tre e e rouler. De mme, une fois lobjet termin et referm, un utilisateur na pas ` sinquiter e e e a e de son fonctionnement interne. Mieux, concernant les voitures, il nest pas possible de se tromper et de mettre de lessence dans le radiateur puisque le radiateur nest pas accessible. De mme, lencapsulation permet de protger ce qui doit ltre en ne laissant e e e accessible que ce qui ne risque rien.

1.4

Pour rsumer e

La programmation objet force le programmeur ` avoir une rexion prliminaire. a e e On a moins la possibilit de programmer ` la va-vite; un plan de programme est quasi e a indispensable. En particulier : Les objets doivent tre dclars et typs. e e e e Des mcanismes de contrle permettent de vrier la cohrence interne des objets. e o e e Un objet peut hriter des proprits qui ont t dnies pour un autre objet. e ee ee e Enn, lobjet permet une encapsulation du programme : une fois quon a dni e un objet et les fonctions qui sy rattachent, on na plus besoin de soccuper de la cuisine interne de lobjet.

1.5

Devez-vous vous mettre ` lobjet ? a

Nous venons de le voir, la programmation objet a des avantages, mais elle a aussi des inconvnients. En premier lieu, elle nest pas facile ` apprendre et on trouve assez e a

16

CHAPITRE 1. INTRODUCTION

peu de tutoriaux disponibles (cest dailleurs ce vide qui a donn naissance au prsent e e ouvrage). Ensuite, la mise en route dun projet est passablement plus lourde ` grer quen a e programmation classique o` tout peut se faire petit ` petit. Se pose donc la lgitime u a e question : doit-on ou ne doit-on pas faire de lobjet ? Pour la petite programmation de tous les jours, un nettoyage des donnes, une e analyse univarie/bivarie, une rgression, tous les outils existent dj`, pas besoin e e e ea de S4. Pour les projets un peu plus importants, quand vous travaillez sur un nouveau concept, sur des donnes complexes dpassant le simple cadre du numeric et face e tor, alors lobjet devient une force : plus dicile au dpart, mais bien moins buggu e e et plus facilement manipulable ` larrive. a e Enn, la construction dun package devrait toujours tre rchie et structure. e e e e Dans ce cadre, la programmation objet est conseille. e

1.6

Le ct obscur de la programmation o e

Pour terminer avec cette longue introduction, une petite digression.

1.6.1

Daccord, pas daccord

Vous tes en train de lire un manuel de programmation objet. Vous tes en train e e dapprendre une nouvelle mthode. Sachez quil nexiste pas une mais des mani`res e e de programmer : ` ce sujet, les informaticiens ne sont pas toujours daccord entre eux. a Ce livre suit une certaine vision, celle de son auteur. Des gens tr`s comptents sont e e daccord, dautres le sont moins... Y a-t-il une vrit et si oui, o` se trouve-t-elle ? Myse e u t`re. Nanmoins, pour essayer de donner une vision la plus large possible, il arrivera e e que ce livre vous prsente plusieurs points de vue, celui de lauteur, mais aussi celui de e lecteurs qui ont ragi ` ce quils lisaient et qui ont fait valoir une autre vision des choses. e a Ainsi, lecteur avis, vous aurez tous les lments en main, e ee vous pourrez peser le pour et le contre et vous choisirez votre voie en toute libert, e a ` la lumi`re de la connaissance... e

1.6.2

Les fuses, la bourse, les bugs... et les coupables ! e

Quand les hommes ont commenc ` envoyer des fuses dans lespace 3 et quelles ont ea e explos en plein vol, ils ont cras une petite larme et ont cherch les causes de lchec. e e e e e Comme il fallait bien brler quelquun, ils ont cherch un coupable. Et ils ont trouv... les u e e informaticiens. Cest pas dnot faute, ont dclar les informaticiens tout marris, cest e e un fait avr intrins`que aux ordinateurs : tous les programmes sont buggus ! Sauf que ee e e dans le cas prsent, la facture du bug tait plutt sale... e e o e
3. Ou quand ils ont con la bourse, les hpitaux, les ches de paye...aux ordinateurs. e o

1.6. LE COTE OBSCUR DE LA PROGRAMMATION

17

Des gens tr`s forts et tr`s intelligents ont donc cherch des moyens de rendre la proe e e grammation moins buggue. Ils ont fabriqu des nouveaux langages et dni des r`gles e e e e de programmation. On appelle a la programmation propre ou les bonnes pratiques. Vous c trouverez une proposition de bonnes pratiques en annexe section ?? page ??. Certaines oprations, certaines pratiques, certaines mani`res de programmer sont donc qualies de e e e bonnes, belles ou propres ; dautres au rebours sont qualis de mauvaises, dangereuses, e impropres voire sales (Le terme exact consacr par les informaticiens est crade...) Il ne e sagit pas l` de jugements de valeur, ce sont simplement des qualicatifs qui indiquent a que ce type de programmation favorise lapparition derreurs dans le code. Donc ` viter ae durgence.

1.6.3

R, langage propre ?

R nest pas un langage tr`s propre. Quand un informaticien veut ajouter un e package, il est libre de faire ` peut pr`s ce quil veut (ce qui est une grande a e force) y compris la dnition dinstructions surprenantes (ce qui est une e faiblesse). Une instruction surprenante est une instruction dont le fonctionnement est contraire ` lintuition. Par exemple, sachant que numeric() dsigne un numeric vide et a e que integer() est en entier vide, comment dsigner une matrice vide ? Toute dnition e e autre que matrix() serait surprenante. De nombreuses surprises existent dans R... (Voir la section 4.6 page 33 pour plus de dtails sur les objets vides). R permet donc de faire e tout un tas doprations dangereuses. Il sera nanmoins parfois possible de le rendre e e propre en nous auto-interdisant des manipulations. Mais a ne sera pas toujours le cas, c nous serons amens ` utiliser des outils impropres. En tout tat de cause, les passages e a e dangereux seront signals par le petit logo qui orne le dbut de ce paragraphe. e e Mais tout le monde ne partage pas ce point de vue : On a nanmoins besoin des e langages ultra-exibles et peu contraints, prcise un relecteur, parce quils rendent cere taines applications faciles ` programmer alors que les langages propres ne les g`rent pas a e ou mal. Dans ce genre de cas, utiliser un langage propre revient un peu ` prendre un a marteau-piqueur pour craser une noix. En particulier, crire le coeur dun programme e e en C (au lieu de R) peut accroitre la rapidit dexcution par un facteur 10 ou 20. e e Cest vrai. Mais tout dpend du niveau du programmeur : ` haut niveau, pour ceux e a qui ne font pas derreur, lecacit peut primer sur la propret. A notre niveau, il me pae e rait surtout important de programmer proprement pour rsoudre le probl`me principal : e e programmer sans bug. En vous souhaitant de ne jamais tomber du ct obscur de la programmation... oe

18

CHAPITRE 1. INTRODUCTION

Chapitre 2

Gnralits sur les objets e e e


2.1 Dnition formelle e

Un objet est un ensemble cohrent de variables et de fonctions qui tournent autour e dun concept central. Formellement, un objet est dni par trois lments : e ee La classe est le nom de lobjet. Cest aussi son architecture, la liste de variables et de fonctions qui le compose. Les variables de lobjet sont appeles attributs. e Les fonctions de lobjet sont appeles mthodes. e e Dans lintroduction, nous avions dni un objet de classe IMC. Il avait pour attributs e poids et taille, pour mthode show. e

2.1.1

Les attributs

Les attributs sont simplement des variables types. Une variable type est une variable e e dont on a x la nature une bonne fois pour toutes. Dans R, on peut crire poids <e e 62 (` ce stade, poids est un numeric) puis poids <- "bonjour" (poids est devenu un a character). Le type de la variable poids peut changer. En programmation objet, il ne sera pas possible de changer le type des attributs en cours de programmation 1 . Cela semble tre une contrainte, cest en fait une scurit. En e e e eet, si une variable a t cre pour contenir un poids, elle na aucune raison de recevoir e e ee une cha de caract`res... sauf erreur de programmation. ne e

2.1.2

Les mthodes e

On distingue 4 types doprations ` faire sur les objets : e a Mthodes de cration : entrent dans cette catgorie toutes les mthodes pere e e e mettant de crer un objet. La plus importante sappelle le constructeur. Mais son e utilisation est un peu rugueuse pour lutilisateur. Le programmeur crit donc des e
1. Hlas, avec R et la S4, cest possible. Mais comme cest sans doute lopration la plus impropre de e e toute lhistoire de linformatique, nous prfrons oublier et faire comme si ca ne ltait pas. ee e

19

20

CHAPITRE 2. GENERALITES SUR LES OBJETS mthodes faciles dacc`s pour crer un objet ` partir de donnes, dun chier ou ` e e e a e a partir dun autre objet (par exemple numeric ou read.csv2). Validation : en programmation objet, il est possible de vrier que les attributs e respectent certaines contraintes. Il est galement possible de crer des attributs ` e e a partir de calculs faits sur les autres attributs. Tout cela rentre dans la validation dobjet. Manipulation des attributs : modier et lire les attributs nest pas aussi anodin que dans la programmation classique. Aussi, ddie-t-on des mthodes ` la manie e a pulation des attributs (par exemple names et names<-). Autres : tout ce qui prc`de constitue une sorte de minimum lgal ` programmer e e e a pour chaque objet. Reste ensuite les mthodes spciques ` lobjet, en particulier e e a les mthodes dachage et les mthodes eectuant des calculs. e e

Les mthodes sont des fonctions types. Le type dune fonction est la juxtaposition e e de deux types : son type entre et son type sortie. e Le type-entre est simplement lensemble des types des arguments de la fonction. e Par exemple, la fonction trace prend pour argument une matrice, son type-entre e est donc matrix. Le type-sortie est le type de ce que la fonction retourne. Par exemple, la fonction trace retourne un nombre, son type-sortie est donc numeric. Au nal, le type dune fonction est (type-entree,type-sortie). On le note TypeSortie <- fonction(TypeEntree). Par exemple, le type de la fonction trace est numeric <- trace(matrix).

2.2

Dessiner, cest gagner !

Il vaut mieux un bon dessin quun long discours. La maxime sapplique particuli`e rement bien ` la programmation objet. Chaque classe est reprsente par un rectangle a e e dans lequel sont nots les attributs et les mthodes avec leur type. e e Lhritage (voir section 9 page 69) entre deux classes est not par une `che, du ls e e e vers le p`re. e

Chapitre 3

Exemple de travail
Plutt que dinventer un exemple avec des wiz, des spoun ou des concepts mao thmatiques complexes trus dquations, voil` un cas rel (fortement simpli, mais e e e a e e rel) : la doctoresse Tam travaille sur des patientes anorexiques. Semaine apr`s semaine, e e elle mesure leur IMC (exemple 17, puis 17.2, puis 17.1, puis 17.4). Pour une patiente, la suite obtenue forme une trajectoire (exemple (17, 17.3, 17.2, 17.4)). Graphiquement, on obtient :
18.0 16.0 1 17.0

LIMC de la demoiselle augmente progressivement. Lorsquon dispose de plusieurs trajectoires, les graphes deviennent illisibles :

10 1

14

18

Do` la ncessit, pour y voir plus clair, de regrouper les trajectoires. u e e 21

22

CHAPITRE 3. EXEMPLE DE TRAVAIL

Elle veut donc classer ses patientes en groupe selon des crit`res bien prcis : e e [AGrandi] (Oui)/(Non), [DemandeAVoirSesParents] (Oui)/(Non)/(Refuse), [RemangeRapidement] (Oui)/(Non). Au nal, son but est de comparer direntes mani`res e e de regrouper les trajectoires.

3.1

Analyse du probl`me e

Ce probl`me est dcoupable en trois objets. e e Le premi`re sera celui qui contiendra les trajectoires des patientes. e Le deuxi`me reprsentera un dcoupage en groupe (que nous appellerons une pare e e tition). Le troisi`me sera un mlange des deux : les trajectoires partitionnes en groupe. e e e

3.2

Lobjet Trajectoires

Tam nous prvient que pour un groupe donn, les mesures sont faites soit toutes les e e semaines, soit tous les quinze jours. Lobjet Trajectoires doit en tenir compte. Il sera donc dni par deux attributs : e temps : numro de la semaine o` les mesures sont eectues. Pour simplier, la e u e semaine o` commence le suivi du groupe aura le numro 1. u e traj : les trajectoires de poids des patientes Exemple : temps = 2, 4, 5) (1, 15 15.1 15.2 15.2 16 15.9 16 16.4 traj = 15.2 15.2 15.3 15.3 15.7 15.6 15.8 16

Quelle(s) mthode(s) pour cet objet ? Tam nous dit que dans ce genre de recherche, il e y a souvent des donnes manquantes. Il est important de savoir combien il y en a. Nous e dnirons donc une premi`re mthode qui comptera le nombre de valeurs manquantes. e e e La deuxi`me mthode sera a cheval entre les objets Trajectoires et Partition 1 : e e ` une mani`re classique de construire une partition de groupes est de distinguer les patients e selon leur IMC initial : dans notre exemple, on pourrait considrer deux groupes, les IMC e initial faible et IMC initial haut. Il faudra donc dnir une mthode de dcoupage selon e e e lIMC initial et le nombre de groupes souhait. e
1. En R, ca na pas beaucoup dimportance mais dans un langage objet classique, chaque mthode e doit obligatoirement appartenir a une classe et une seule. Pour nous conformer aux r`gles de lobjet, ` e nous inclurons donc cette mthode dans Trajectoires. e

3.3. LOBJET PARTITION

23

Enn, la prsence de valeurs manquantes peut interdire lutilisation doutils statise tiques. Il sera donc intressant de pouvoir les imputer 2 . La troisi`me mthode imputera e e e les manquantes.

3.3

Lobjet Partition

Une partition est un ensemble de groupe. Par exemple les groupes pourraient tre e A ={T1,T3} et B={T2,T4}. Il sera sans doute plus simple de les considrer comme e un vecteur ayant pour longueur le nombre de patientes : {A,B,A,B}. Dans un certain nombre de cas, il faudra galement conna le nombre de groupe, en particulier quand e tre un groupe est manquant : si Tam classe ses ados en trois groupes et quelle obtient la partition {A,C,C,A}, il est important de garder en mmoire que le groupe B existe, e mme sil ne contient personne. Do` deux attributs pour lobjet Partition : e u nbGroupes : donne le nombre de groupes. part : la suite des groupes auxquels les trajectoires appartiennent. Exemple : nbGroupe = 3 A B part = A C Certains statisticiens (et mme certains logiciels) transforment les variables e nominales en chires. Nous pourrions dnir part comme un vecteur dentier. e Cest beaucoup plus pratique, sentend-on dire rguli`rement. Sauf que ce e e faisant, on trompe R sur la nature de nos variables : R est conu pour savoir calculer la c moyenne dune variable numrique, mais refuser de calculer la moyenne dune variable e nominale (un factor). Si nous codons part avec des chires, R acceptera de calculer la moyenne dune partition, ce qui na aucun sens. Ca serait un peu comme faire la moyenne de Tortue, Girafe et Tigre... Une variable nominale doit donc tre code par un factor, e e une numrique par un numeric. Oui, nous savons, dans certains cas, il serait un peu plus e pratique de coder part par des nombres, mais cest beaucoup plus dangereux. Donc ` a viter durgence ! e

3.4

Lobjet TrajDecoupees

TrajDecoupees sera lobjet regroupant un objet Trajectoires et plusieurs Partition. En eet, il est possible que pour un ensemble de trajectoires, plusieurs partitionnements soient intressants. Il sera donc hritier de Trajectoires. Par contre, il ne e e
2. Limputation dune valeur manquante est son remplacement par une valeur que lon devine grce a aux autres valeurs... avec plus ou moins de bonheur !

24

CHAPITRE 3. EXEMPLE DE TRAVAIL

sera pas hritier de Partition parce que les deux classes ne partagent pas vraiment de e proprits. Pour plus de dtail, voir section 9 page 69. ee e temps : le temps auquel les mesures sont eectues (comme dans trajectoires) e traj : les trajectoires de poids des patientes (comme dans trajectoires) listePartitions : un ensemble de partitions. Exemple : temps = 2, 4, 5) (1, 15 15.1 15.2 15.2 16 15.9 16 16.4 traj = 15.2 15.2 15.3 15.3 15.5 15.6 15.8 16 nbGroupe = 3 A B listePartitions = part = A C

nbGroupe = 2 A B part = A A

3.5

Plan danalyse

Pour rsumer, nous avons donc trois classes : e

` 3.6. APPLICATION A R

25

La `che pleine (du ls vers le p`re) indique lhritage, la `che en pointill dsigne e e e e e e linclusion dun objet dans lautre sans hritage. e

3.6

Application ` R a

Et R dans tout ca, seriez-vous en droit de rclamer ? Cest galement une des caract e e e ristiques des langages objets, nous avons fait une analyse relativement pousse (pousse e e pour un probl`me aussi simple que le ntre) et il ny a toujours pas la moindre ligne e o de code R... Thoriquement, on pourrait mme choisir de coder dans un autre langage. e e Mais bon, l` nest pas le sujet du jour. a Appliques ` R, les mthodes dnies au 2.1.2 page 19 deviennent : e a e e Mthodes de cration : la mthode de cration principale porte le nom de la e e e e classe. Validation : Cela dpend de lobjet. e Manipulation des attributs : pour chaque attribut, il faudra une mthode pere mettant daccder ` sa valeur et une mthode permettant de la modier. e a e Autres : les mthodes autres dpendent des particularits de lobjet, ` lexcepe e e a tion toutefois des mthodes dachage. Pour lachage, show permet un achage e sommaire de lobjet quand on tape son nom dans la console. print donne un achage plus complet. plot est lachage graphique. Pour nir avec les particularits de R, la majorit des langages objets forcent e e le programmeur ` grouper tout ce qui concerne un objet dans un mme a e endroit. Cela sappelle lencapsulation. R na pas cette proprit : vous pouvez ee tr`s bien dclarer un objet, puis un autre, puis une mthode pour le premier objet, puis e e e dclarer un troisi`me objet, et ainsi de suite. Cest fortement dconseill, et de surcroit e e e e facilement vitable en suivant une r`gle toute simple : e e ` A chaque objet son chier. Tout ce qui concerne un objet doit tre dans un unique cher, un chier ne doit e contenir que des informations relatives ` un unique objet. Cela sera repris plus en dtail a e lors de la cration de package section ?? page ??. e

26

CHAPITRE 3. EXEMPLE DE TRAVAIL

Deuxi`me partie e

Les bases de lobjet

27

Chapitre 4

Dclaration des classes e


Nous lavons voqu dans les chapitres prcdents, une classe est un ensemble date e e e tributs et de mthodes. Nous allons maintenant dnir les uns et les autres. e e Dans la majorit des langages objets, la dnition de lobjet contient les e e attributs et les mthodes. En R, la dnition ne contient que les attributs. e e Les mthodes sont prcises ensuite. Cest dommage, ca attnue la puissance e e e e de lencapsulation, mais cest comme ca. Lutilisateur averti (cest ` dire vous) peut a compenser manuellement, par exemple en se forant ` dnir attributs et mthodes en c a e e bloc dans un mme chier, et en utilisant un chier par objet. e Plus de conseils sur lart de bien encapsuler section ?? page ??.

4.1

Dnition des attributs e

La premi`re tape est de dnir les attributs de lobjet proprement dit. Cela se fait e e e a ` laide de linstruction setClass. setClass est une fonction qui prend deux arguments (et quelques autres ingrdients que nous verrons plus tard). e Class (avec une majuscule) est le nom de la classe que nous sommes en train de dnir. e representation est la liste des attributs de la classe. Comme nous lavons vu dans lexemple introductif, la programmation objet fait du contrle de type, cest ` dire quelle ne permettra pas ` une cha de caract`res dtre o a a ne e e range l` o` devrait se trouver en entier. Chaque attribut doit tre dclar avec son type. e a u e e e
> setClass ( + Class = " Trajectoires " , + representation = representation ( + temps = " numeric " , + traj = " matrix " + ) + ) [1] " Trajectoires "

29

30

CHAPITRE 4. DECLARATION DES CLASSES Malheureusement, il est tout de mme possible de ne pas typer (ou de mal e typer) en utilisant les listes. Le non typage est fortement dconseill, mais e e lors de lutilisation de listes, il ny a pas dautre option.

4.2

Constructeur par dfaut e

On peut ensuite crer un objet trajectoire grce au constructeur new : e a


> new( Class = " Trajectoires " ) An object of class " Trajectoires " Slot " temps " : numeric (0) Slot " traj " : <0 x 0 matrix >

Comme vous pouvez le constater, lachage nest pas extraordinaire. Il sera important de dnir une mthode pour lamliorer. e e e En gnral, on dnit un objet en spciant les valeurs de ses attributs. On doit ` e e e e a chaque fois prciser le nom de lattribut en question : e
> new( Class = " Trajectoires " , temps = c (1 ,3 ,4)) An object of class " Trajectoires " Slot " temps " : [1] 1 3 4 Slot " traj " : <0 x 0 matrix > > new( Class = " Trajectoires " , temps = c (1 ,3) , traj =matrix (1:4 , ncol =2)) An object of class " Trajectoires " Slot " temps " : [1] 1 3 Slot " traj " : [ ,1] [ ,2] [1 ,] 1 3 [2 ,] 2 4

Naturellement, un objet se stocke dans une variable comme nimporte quelle autre valeur de R. Pour illustrer nos dires, nous allons constituer une petite base de travail. Trois hpitaux participent ` ltude. La Piti Salptri`re (qui na pas encore rendu son o a e e e e chier de donnes, honte ` eux), Cochin et Sainte-Anne : e a
> trajPitie <- new( Class = " Trajectoires " ) > trajCochin <- new( + Class = " Trajectoires " ,

4.3. ACCEDER AUX ATTRIBUTS


+ temps = c (1 ,3 ,4 ,5) , + traj = rbind ( + c (15 ,15.1 ,15.2 ,15.2) , + c (16 ,15.9 ,16 ,16.4) , + c (15.2 , NA ,15.3 ,15.3) , + c (15.7 ,15.6 ,15.8 ,16) + ) + ) > trajStAnne <- new( + Class = " Trajectoires " , + temps = c (1:10 ,(6:12) * 2) , + traj = rbind ( + matrix( seq (16 ,19 , length =17) , ncol =17 , nrow =50 ,byrow=TRUE) , + matrix( seq (15.8 ,18 , length =17) , ncol =17 , nrow =30 ,byrow=TRUE) + )+rnorm(17 * 80 ,0 ,0.2) + )

31

4.3

Accder aux attributs e


Toute cette section est place sous le double signe e du danger... et du danger...

Lacc`s aux attributs se fait grce ` loprateur @ : e a a e


> trajCochin@temps [1] 1 3 4 5 > trajCochin@temps <- c (1 ,2 ,4 ,5) > trajCochin An object of class " Trajectoires " Slot " temps " : [1] 1 2 4 5 Slot " traj " : [ ,1] [ ,2] [1 ,] 15.0 15.1 [2 ,] 16.0 15.9 [3 ,] 15.2 NA [4 ,] 15.7 15.6

[ ,3] 15.2 16.0 15.3 15.8

[ ,4] 15.2 16.4 15.3 16.0

Comme nous le verrons par la suite, lutilisation de @ est ` viter. En eet, il ne fait ae pas appel aux mthodes de vrication. Lutilisation que nous prsentons ici (achage e e e dun attribut, et pire encore aectation dune valeur ` un attribut) est donc ` proscrire a a dans la plupart des cas. En tout tat de cause, lutilisateur nal ne devrait jamais avoir e a ` lutiliser. Il est galement possible dutiliser les fonctions attr ou attributes, mais e cest largement pire : en eet, si on fait une simple erreur de typographie, on modie la structure de lobjet. Et a, cest tr`s tr`s tr`s mal ! c e e e

32

CHAPITRE 4. DECLARATION DES CLASSES

4.4

Valeurs par dfaut e

On peut dclarer un objet en lui donnant des valeurs par dfaut. A chaque cration, e e e si lutilisateur ne spcie pas les valeurs des attributs, ceux-ci en auront quand mme e e une. Pour cela, on doit ajouter largument prototype ` la dnition de lobjet : a e
> setClass ( + Class = " TrajectoiresBis " , + representation = representation ( + temps = " numeric " , + traj = " matrix " + ), + prototype = prototype ( + temps = 1 , + traj = matrix (0) + ) + ) [1] " TrajectoiresBis "

Linitialisation par dfaut tait quelque chose de ncessaire ` lpoque loine e e a e taine o`, si on ninitialisait pas une variable, on risquait dcrire dans la u e mmoire syst`me (et donc de provoquer un blocage de lordinateur, la perte e e de notre programme et dautres trucs encore plus terribles). Aujourdhui, une telle chose nest plus possible. Si on ninitialise pas un attribut, R lui donne pour valeur un objet vide du type adquat. e Du point de vue philosophique, lorsquon cre un objet, soit on conna sa valeur e t auquel cas on la lui aecte, soit on ne la conna pas auquel cas il ny a aucune raison de t lui donner une valeur plutt quune autre. Lutilisation dune valeur par dfaut semble o e donc tre plus une rminiscence du pass quune relle ncessit. Elle na plus lieu dtre. e e e e e e e De plus, dans le feu de la programmation, il peut arriver quon oublie de donner a ` un objet sa vraie valeur. Sil existe une valeur par dfaut, elle sera utilise. Sil ny e e a pas de valeur par dfaut, cela provoquera une erreur... ce qui, dans ce cas prcis, est e e prfrable, cela attire notre attention et nous permet de corriger. Donc, les valeurs par ee dfaut autres que les valeurs vides sont ` viter. e ae

4.5

Supprimer un objet

Dans le cas prcis de lobjet trajectoires, il ny a pas vraiment de valeur par dfaut e e qui simpose. Il est donc prfrable de conserver la classe comme elle a t initialement ee ee dnie. La classe TrajectoiresBis na plus raison dtre. On peut la supprimer grce e e a a ` removeClass :
> removeClass( " TrajectoiresBis " ) [1] TRUE

4.6. LOBJET VIDE

33

> new( Class = " TrajectoiresBis " ) Error in getClass ( Class , where = topenv ( parent . frame ())) : " TrajectoiresBis " is not a defined class

Supprimer la dnition dune classe ne supprime pas les mthodes qui lui sont e e associes. Pour supprimer dnitivement une classe dans le sens classique du e e terme, il faut supprimer la classe puis supprimer toutes ses mthodes... e En particulier, vous crez une classe et ses mthodes. Ca ne marche pas comme prvu. e e e Vous dcidez de tout reprendre ` zro. Vous eacez donc la classe. Si vous la recrez, e a e e toutes les anciennes mthodes seront ` nouveau actives. e a

4.6

Lobjet vide

Certaines fonctionnalits objets appellent la fonction new sans lui transmettre e dargument. Par exemple, nous utiliserons dans la section sur lhritage linstruction e as(tdCochin,"Trajectoires") (voir section 9.8 page 77). Cette instruction fait appel a ` new("Trajectoires"). Il est donc indispensable, lors de la construction dun objet, de toujours garder ` lesprit que new doit tre utilisable sans argument. Comme les valeurs a e par dfaut sont dconseilles, il faut prvoir la construction de lobjet vide. Cela sera e e e e important en particulier lors de la construction de la mthode show. e Un objet vide est un objet possdant tous les attributs normaux dun objet, mais e ceux-ci sont vides, cest ` dire de longueur zro. Par contre, un objet vide a une classe. a e Ainsi, un numeric vide est dirent dun integer vide. e
> identical ( numeric () , integer ()) [1] FALSE

Quelques r`gles ` conna concernant les objets vides : e a tre numeric() et numeric(0) dsignent un numeric vide. e Mme chose pour character() et character(0). e Mme chose pour integer() et integer(0). e Par contre, factor() dsigne un factor vide, factor(0) dsigne un factor de e e longueur 1 et contenant llement zro. e e Plus problmatique, matrix() dsigne une matrice ` une ligne et une coe e a lonne contenant NA. En tout tat de cause, a nest pas la matrice vide (son e c attribut length vaut 1). Pour dnir une matrice vide, il faut utiliser mae trix(nrow=0,ncol=0). Mme chose pour les array(). e NULL reprsente lobjet nul. Ainsi, NULL est de classe NULL alors que numeric() est e de classe numeric. Pour tester quun objet est lobjet vide, il faut tester son attribut length. De mme, e si nous dcidons de dnir la mthode length pour nos objets, il faudra prendre garde e e e

34

CHAPITRE 4. DECLARATION DES CLASSES

a ` ce que length(monObjet)=0 soit vrai si et seulement si lobjet est vide (pour assurer une certaine cohrence ` R). e a

4.7

Voir lobjet

Vous venez de crer votre premi`re classe. Flicitations ! Pour pouvoir vrier ce que e e e e vous venez de faire, plusieurs instructions permettent de voir la classe et sa structure. Le terme savant dsignant ce qui permet au programme de voir le contenu ou la structure e des objets sappelle lintrospection. slotNames donne le nom des attributs. getSlots donne le nom des attributs et leur type. getClass donne les noms des attributs et leur type, mais aussi les hritiers et les e anctres. Comme lhritage est encore terra incognita, ca ne fait pour linstant aucune e e dirence : e
> slotNames( " Trajectoires " ) [1] " temps " " traj " > g e t S l o t s ( " Trajectoires " ) temps " numeric " traj " matrix "

> getClass ( " Trajectoires " ) Class " Trajectoires " [ in " . GlobalEnv " ] Slots : Name : temps Class : numeric traj matrix

Chapitre 5

Les mthodes e
Un des intrts de lobjet est de pouvoir dnir des fonctions qui vont adapter leur ee e comportement ` lobjet. Exemple que vous connaissez dj`, la fonction plot ragit difa ea e fremment selon la classe de ses arguments : e
> > > > > taille <- rnorm(10 ,1.70 ,10) poids <- rnorm(10 ,70 ,5) groupe <- as . f a c t o r ( rep ( c ( " A " ," B " ) ,5)) plot ( taille ~ poids ) plot ( taille ~ groupe )
10 10

EMPTY

q q

taille

taille
q q

10

15

15

10

64

66

68

70 poids

72

74

76

A groupe

EMPTY

Le premier plot trace un nuage de points, le deuxi`me dessine des boites ` mouse a taches. De mme, il va tre possible de dnir un comportement spcique pour nos e e e e trajectoires.

5.1

setMethod

Pour cela, on utilise la fonction setMethod. Elle prend trois arguments : 35

36

CHAPITRE 5. LES METHODES 1. f est le nom de la fonction que nous sommes en train de rednir. Dans notre cas, e plot 2. signature est le nom de la classe ` laquelle elle sapplique. Nous aurons loccasion a dy revenir section 8.2 page 64 3. definition est la fonction ` utiliser. Dans notre cas, nous allons simplement utia liser un matplot en prenant en compte les temps des mesures et en les achant sur laxe des abscisses

> setMethod( + f = " plot " , + signature = " Trajectoires " , + d e f i n i t i o n = function (x ,y ,...){ + matplot( x@temps , t ( x@traj ) , xaxt = " n " , type = " l " , + ylab = " " , xlab = " " , pch =1 , col =1 , lty =1) + a x i s (1 , at = x@temps ) + } + ) [1] " plot " > plot ( trajCochin ) > plot ( trajStAnne ) EMPTY
16.2 19 1 2 4 5 16 15.0 1 17 15.4 18 15.8

12

16

20

24

EMPTY

Petite remarque : R nous impose, lors de la rednition dune fonction, dutiliser les e mmes arguments que la fonction en question. Pour conna e tre les arguments de plot, on peut utiliser args
> args ( plot ) function (x , y , ...) NULL

5.2. SHOW ET PRINT

37

Nous sommes donc obligs dutiliser function(x,y,...) mme si nous sae e vons dors et dj` que largument y na pas de sens. De plus, les noms par ea dfaut ne sont pas vraiment uniformiss, certaines fonctions appellent object, e e dautres .Object, dautres encore x. R-la-golette vogue au gr de ses programmeurs... e e

5.2

show et print

show et print servent pour lachage. Nous allons les dnir pour les trajectoires. e args(print) nous indique que print prend pour argument (x,...). Donc :
> setMethod( " print " ," Trajectoires " , + function (x ,...){ + cat ( " * * * Class Trajectoires , method Print * * * \ n " ) + cat ( " * Temps = " ); print ( x@temps ) + cat ( " * Traj = \ n " ); print ( x@traj ) + cat ( " * * * * * * * Fin Print ( trajectoires ) * * * * * * * \ n " ) + } + ) [1] " print " > print ( trajCochin ) * * * Class Trajectoires , method Print * * * * Temps = [1] 1 2 4 5 * Traj = [ ,1] [ ,2] [ ,3] [ ,4] [1 ,] 15.0 15.1 15.2 15.2 [2 ,] 16.0 15.9 16.0 16.4 [3 ,] 15.2 NA 15.3 15.3 [4 ,] 15.7 15.6 15.8 16.0 * * * * * * * Fin Print ( trajectoires ) * * * * * * *

Pour Cochin, le rsultat est satisfaisant. Pour Sainte-Anne (qui compte 80 lignes), e on ne verrait pas grand-chose, do` le besoin dune deuxi`me mthode dachage. u e e show est la mthode utilise quand on tape le nom dun objet. Nous allons donc la e e rednir en prenant en compte la taille de lobjet : sil y a trop de trajectoires, show nen e achera quune partie.
> setMethod( " show " ," Trajectoires " , + function ( object ){ + cat ( " * * * Class Trajectoires , method Show * * * \ n " ) + cat ( " * Temps = " ); print ( object@temps ) + nrowShow <- min (10 , nrow ( object@traj )) + ncolShow <- min (10 , ncol ( object@traj )) + cat ( " * Traj ( limit ` une matrice 10 x10 ) = \ n " ) e a + print ( formatC ( object@traj [1: nrowShow ,1: ncolShow ]) , + quote =FALSE) + cat ( " * ... ...\ n " ) + cat ( " * * * * * * * Fin Show ( trajectoires ) * * * * * * * \ n " ) + } + )

38

CHAPITRE 5. LES METHODES

[1] " show " > trajStAnne * * * Class Trajectoires , method Show * * * * Temps = [1] 1 2 3 4 5 6 7 8 9 * Traj ( limit ` une matrice 10 x10 ) = e a [ ,1] [ ,2] [ ,3] [ ,4] [ ,5] [ ,6] [1 ,] 16.25 16.1 16.16 16.53 16.67 17.2 [2 ,] 16.23 16.36 16.45 16.4 17.14 17 [3 ,] 15.89 16.02 16.15 16.69 16.77 16.62 [4 ,] 15.63 16.25 16.4 16.6 16.65 16.96 [5 ,] 16.16 15.85 15.97 16.32 16.73 16.94 [6 ,] 15.96 16.2 16.53 16.4 16.47 16.95 [7 ,] 16.03 16.33 16.23 16.67 16.79 17.14 [8 ,] 15.69 16.06 16.63 16.72 16.81 17.16 [9 ,] 15.82 16.17 16.75 16.76 16.78 16.51 [10 ,] 15.98 15.76 16.1 16.54 16.78 16.89 * ... ... * * * * * * * Fin Show ( trajectoires ) * * * * * * *

10 12 14 16 18 20 22 24 [ ,7] 17.55 16.84 17.52 17.02 16.73 16.73 17 16.98 17.19 17.22 [ ,8] 17.3 17.25 17.26 17.39 16.98 17.36 17.35 17.41 17.21 17.18 [ ,9] 17.47 17.98 17.46 17.5 17.64 17.33 17.58 17.51 17.84 16.94 [ ,10] 17.55 17.43 17.6 17.67 17.72 17.55 17.99 17.43 17.95 17.36

Reste un probl`me ` rgler. Nous avons vu section 4.6 page 33 que new devait tre e a e e utilisable sans argument. Or, il ne lest plus :
> new( " Trajectoires " ) * * * Class Trajectoires , method Show * * * * Temps = numeric (0) * Traj ( limit ` une matrice 10 x10 ) = e a Error in print ( formatC ( object@traj [1: nrowShow , 1: ncolShow ]) , quote = FALSE ) : erreur lors de l ' valuation de l ' argument ' x ' lors de e la s lection d ' une m thode pour la fonction ' print ' e e

En eet, new cre un objet, puis lache en utilisant show. Dans le cas de new sans e argument, lobjet vide est pass ` show. Or, show tel que nous lavons conu ne peut pas ea c traiter lobjet vide. Dune mani`re plus gnrale, toutes nos mthodes doivent prendre en compte le fait e e e e quelles auront peut-tre ` traiter lobjet vide : e a
> setMethod( " show " ," Trajectoires " , + function ( object ){ + cat ( " * * * Class Trajectoires , method Show * * * \ n " ) + cat ( " * Temps = " ); print ( object@temps ) + nrowShow <- min (10 , nrow ( object@traj )) + ncolShow <- min (10 , ncol ( object@traj )) + cat ( " * Traj ( limit ` une matrice 10 x10 ) = \ n " ) e a + i f ( length ( object@traj ) ! = 0){ + print ( formatC ( object@traj [1: nrowShow ,1: ncolShow ]) , + quote =FALSE) + } e l s e {} + cat ( " * ... ...\ n " )

5.3. SETGENERIC
+ + + ) cat ( " * * * * * * * Fin } Show ( trajectoires ) * * * * * * * \ n " )

39

[1] " show " > new( " Trajectoires " ) * * * Class Trajectoires , method Show * * * * Temps = numeric (0) * Traj ( limit ` une matrice 10 x10 ) = e a * ... ... * * * * * * * Fin Show ( trajectoires ) * * * * * * *

Ca marche ! Nous disposons donc de deux mthodes dachage. Par dfaut, show montre lobjet e e ou une partie de lobjet si celui-ci est trop grand ; print permet dacher lintgralit e e de lobjet.

5.3

setGeneric

Jusqu` prsent, nous navons fait que dnir pour lobjet Trajectoires des ma e e e thodes qui existaient dj` par ailleurs (print existait pour les numeric, pour les chaea racter...). Nous allons maintenant dnir une mthode nouvelle. Pour cela, il nous faut e e la dclarer. Cela se fait ` laide de la fonction setGeneric. A ce stade, une petite digrese a sion sur le concept de gnrique simpose. e e

5.3.1

Gnrique versus Spcique e e e

En S4, les fonctions doivent tre dnies de deux mani`res : gnrique et spcie e e e e e que. La dnition gnrique dune fonction est la donne dun comportement global e e e e (ou conceptuel). La dnition spcique dune fonction est lapplication de ce concept ` e e a un cas particulier. Un exemple va claircir les choses. e plot est une fonction qui reprsente graphiquement des donnes. Telle est sa dnie e e tion gnrique. Le type prcis de reprsentation nentre pas en ligne de compte dans la e e e e dnition gnrique. Celle-ci ne soccupe pas de dtail ou des cas particuliers, elle reste e e e e oue, gnrale... e e plot appliqu ` une variable numeric trace un histogramme. Cest une dnition e a e spcique. Nous ne sommes plus au niveau du concept mais dans la discussion pratique : e il faut dnir le type de graphe qui sera prcisment utilis. Dans notre cas, cest un e e e e histogramme. Une fonction na quune dnition gnrique, mais peut avoir plusieurs dnitions e e e e spciques. Par exemple, plot appliqu ` un (numeric,factor) trace des boites ` mouse ea a taches. Cest une deuxi`me dnition spcique. e e e Dans R, chaque fonction spcique doit ncessairement tre connue du programme e e e comme fonction gnrique : avant dentrer dans les dtails, il faut dnir le concept e e e e global.

40

CHAPITRE 5. LES METHODES

Une mthode nouvelle devra donc en premier lieu tre dclare comme fonction gne e e e e e rique, puis comme fonction spcique. Une fonction dont la gnrique existe dj` (comme e e e ea print) na pas besoin dtre dclare en gnrique et peut directement tre dclare en e e e e e e e e spcique, comme nous lavons fait au paragraphe prcdent. Mais toute fonction noue e e velle doit tre dclare en gnrique. e e e e e

5.3.2

Dnition formelle e

Dnir une fonction gnrique se fait grce ` setGeneric. setGeneric prend deux e e e a a arguments : name est le nom de la mthode que nous allons dnir. e e def est un exemple de fonction qui sera utilis pour la dnir. e e A ce stade, il nest pas possible de la typer puisquelle est gnrique et doit donc tre e e e utilisable pour plusieurs types dirents. e
> setGeneric ( + name= " compterManquantes " , + def = function ( object ){ standardGeneric ( " compterManquantes " )} + ) [1] " compterManquantes "

compterManquantes a donc t ajout ` la liste des mthodes que R connait. Nous ee ea e pouvons maintenant la dnir comme fonction spcique pour lobjet Trajectoires : e e
> setMethod( + f = " compterManquantes " , + signature = " Trajectoires " , + d e f i n i t i o n = function ( object ){ + return ( sum ( is . na ( object@traj ))) + } + ) [1] " compterManquantes " > compterManquantes ( trajCochin ) [1] 1

5.3.3

lockBinding

Il ny a pas de contrle sur lutilisation dun setGeneric : si une fonction o gnrique existe dj`, la nouvelle dnition dtruit lancienne - un peu de e e ea e e la mme mani`re quaecter une valeur ` une variable dtruit la prcdente e e a e e e valeur -. Sauf que dans ce cas prcis, une rednition est plus probablement lie au fait e e e que le programmeur ignore que la fonction existe dj`... Pour se protger de ce probl`me, ea e e il est possible de verrouiller la dnition dune mthode grce ` lockBinding : e e a a

5.4. VOIR LES METHODES

41

> lockBinding ( " compterManquantes " ,. GlobalEnv ) > setGeneric ( + name= " compterManquantes " , + def = function ( object , value ){ + standardGeneric ( " compterManquantes " ) + } + ) Error in assign ( name , fdef , where ) : impossible de changer la valeur d ' un lien verrouill pour ' compterManquantes ' e

Il nest plus possible deacer par erreur le setGeneric. Cette mthode prsente toutefois un inconvnient majeur, celui de la non re e e e excutabilit du code. Pendant la phase de dveloppement, on a tendance ` excuter e e e a e notre code, le modier et le r-excuter. lockBinding empche une telle r excution e e e e e puisquune fonction gnrique ne peut-tre dnie quune fois (et que la r-excution est e e e e e e une seconde dnition). e

5.3.4

Dclaration des gnriques e e e

Une autre mani`re de se protger contre lcrasement des gnriques est de regrouper e e e e e la dclaration des gnriques dans un chier unique. En tout tat de cause, une fonction e e e e gnrique ne concerne pas un objet particulier puisque, par dnition, elle doit sadapter ` e e e a tous les objets. Il est donc prfrable de dclarer toutes les fonctions gnriques ensemble ee e e e en dbut de programme, ventuellement classes par ordre alphabtique. Si par erreur e e e e nous devions dcider de dclarer une gnrique deux fois, il serait alors facile de sen e e e e rendre compte. Plus de dtail sur lart et la mani`re de placer son code dans le chier e e adquat section ?? page ??. e

5.4

Voir les mthodes e

Notre classe commence ` stoer. Il est temps de faire une petite pause et dadmirer a e notre travail. showMethods est la mthode de la situation. Il existe plusieurs mani`res e e de lutiliser. Lune dentre elles permet de voir les noms des mthodes que nous avons e dnies pour une classe donne : e e
> showMethods( class = " Trajectoires " ) Function : initialize ( package methods ) . Object = " Trajectoires " ( inherited from : . Object = " ANY " ) Function : plot ( package graphics ) x = " Trajectoires " Function : print ( package base )

42
x = " Trajectoires " Function : show ( package methods ) object = " Trajectoires "

CHAPITRE 5. LES METHODES

Maintenant que nous avons list ce qui existe, nous pouvons nous intresser dun e e peu plus pr`s ` une mthode particuli`re : getMethod permet dacher la dnition (le e a e e e contenu du corps de la fonction) dune mthode pour un objet donn. Si la mthode en e e e question nexiste pas, getMethod renvoie une erreur :
> getMethod( f = " plot " , signature = " Trajectoires " ) Method Definition : function (x , y , ...) { matplot ( x@temps , t ( x@traj ) , xaxt = " n " , type = " l " , ylab = " " , xlab = " " , pch = 1 , col = 1 , lty = 1) axis (1 , at = x@temps ) } Signatures : x target " Trajectoires " defined " Trajectoires " > getMethod( f = " plot " , signature = " Partition " ) Error in getMethod ( f = " plot " , signature = " Trjectoires " ) : No method found for function " plot " and signature Trjectoires

Plus simplement, existsMethod indique si une mthode est ou nest pas dnie pour e e une classe :
> existsMethod ( f = " plot " , signature = " Trajectoires " ) [1] TRUE > existsMethod ( f = " plot " , signature = " Partition " ) [1] FALSE

Ca nest pas vraiment utile pour lutilisateur, ca lest plus pour le programmeur qui peut crire des choses du genre : Si telle mthode existe pour tel objet, adopte le e e comportement 1, sinon le comportement 2.

Chapitre 6

Construction
La construction regroupe tous les outils permettant de fabriquer une instance correcte dun objet. Entrent dans cette catgorie les mthodes de cration proprement dites e e e (mthodes qui stockent les valeurs dans les attributs) et les mthodes de validation (me e e thodes qui vrient que les valeurs des attribues sont conformes ` ce que le programmeur e e a souhaite).

6.1

Vricateur e

Le vricateur est l` pour contrler quil ny a pas dincohrence interne dans lobjet. e a o e Par exemple, une taille doit tre positive. On lui donne des r`gles et ` chaque cration e e a e dobjet, il vrie que lobjet suit les r`gles. e e Pour cela, on inclut les param`tres de vrication dans la dnition de lobjet luie e e mme via largument validity. Pour lobjet Trajectoires, on peut vouloir vrier e e que le nombre de groupes eectivement prsents dans cluster est infrieur ou gal au e e e nombre de groupes dclar dans nbCluster. e e

43

44

CHAPITRE 6. CONSTRUCTION

> setClass ( + Class = " Trajectoires " , + representation ( temps = " numeric " , traj = " matrix " ) , + v a l i d i t y = function ( object ){ + cat ( " ~ ~ ~ Trajectoires : v rificateur ~ ~ ~ \ n " ) e + i f ( length ( object@temps ) ! = ncol ( object@traj )){ + stop ( " [ Trajectoire : validation ] Le nombre de mesures + temporelles ne correspond pas au nombre de + colonnes de la matrice " ) + } e l s e {} + return (TRUE) + } + ) [1] " Trajectoires " > new( Class = " Trajectoires " , temps =1:2 , traj =matrix (1:2 , ncol =2)) ~ ~ ~ Trajectoires : v rificateur ~ ~ ~ e * * * Class Trajectoires , method Show * * * * Temps = [1] 1 2 * Traj ( limit ` une matrice 10 x10 ) = e a [1] 1 2 * ... ... * * * * * * * Fin Show ( trajectoires ) * * * * * * * > new( Class = " Trajectoires " , temps =1:3 , traj =matrix (1:2 , ncol =2)) ~ ~ ~ Trajectoires : v rificateur ~ ~ ~ e Error in validityMethod ( object ) : [ Trajectoire : validation ] Le nombre de mesures temporelles ne correspond pas au nombre de colonnes de la matrice

Comme vous pouvez le constater, la fonction validity telle que nous venons de la dnir ne prend aucune prcaution concernant lobjet vide. Mais cela na pas dimpore e tance. En eet, new nappelle pas le vricateur quand on ne lui donne pas dargument. e Il est galement possible de dnir une classe, puis plus tard de dnir sa e e e validit grce ` une fonction appele setValidity. De la mme mani`re, il e a a e e e est possible de dnir la representation et le prototype en externe. Mais e cette mani`re de faire est conceptuellement moins propre. En eet, la conception dun e objet doit tre rchie, et non pas faite dajouts ` droite et ` gauche... e e e a a

6.2. LINITIATEUR

45

Le vricateur nest appel QUE lors de la cration initiale de lobjet. Si e e e ensuite il est modi, rien ne va plus, il ny a plus de contrle. Nous pourrons e o bientt corriger cela grce aux setteurs. Pour linstant, on note juste lintrt o a ee de proscrire lutilisation de @ : la modication directe dun attribut nest pas soumise ` a vrication... e
> trajStLouis <- new( + Class = " Trajectoires " , temps = c (1) , traj =matrix (1) + ) ~ ~ ~ Trajectoires : v rificateur ~ ~ ~ e > # ## Pas de v rification , le nombre de mesures temporelles ne e > # ## correspond plus aux trajectoires > ( trajStLouis@temps <- c (1 ,2 ,3)) [1] 1 2 3

6.2

Linitiateur

Le vricateur est une version simplie dun outil plus gnral appel linitiateur. e e e e e Linitiateur est une mthode permettant de fabriquer un objet. Il est appel ` chaque e ea construction dun objet, cest ` dire ` chaque utilisation de la fonction new. a a 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 mme, u ee e les lignes pourraient tre indices par un numro dindividu : e e e T0 15 16 15.2 15.5 T1 15.1 15.9 NA 15.6 T4 15.2 16 15.3 15.8 T5 15.2 16.4 15.3 16

I1 I2 I3 I4

Linitiateur va nous permettre de faire tout a. Linitiateur est une mthode qui, lors c e de lappel de new, fabrique lobjet tel que nous le voulons. Le nom de la mthode est e initialize. initialize utilise une fonction (dnie par lutilisateur) qui prend pour e argument lobjet en train dtre construit et les direntes valeurs ` aecter aux attributs e e a de lobjet. Cette fonction travaille sur une version locale de lobjet. Elle doit se terminer par laectation des valeurs aux attributs de lobjet puis par un return(object).
> setMethod( + f = " initialize " , + signature = " Trajectoires " , + d e f i n i t i o n = function (. Object , temps , traj ){ + cat ( " ~ ~ ~ Trajectoires : initiateur ~ ~ ~ \ n " ) + rownames( traj ) <- paste ( " I " ,1: nrow ( traj ) , sep = " " ) + # Affectation des attributs

46
+ . Object@traj <- traj + + . Object@temps <- temps + # return de l ' objet + return (. Object ) + } + ) [1] " initialize " > new( + Class = " Trajectoires " , + temps = c (1 ,2 ,4 ,8) , + traj =matrix (1:8 , nrow =2) + ) ~ ~ ~ Trajectoires : initiateur ~ ~ ~ * * * Class Trajectoires , method Show * * * * Temps = [1] 1 2 4 8 * Traj ( limit ` une matrice 10 x10 ) = e a [ ,1] [ ,2] [ ,3] [ ,4] I1 1 3 5 7 I2 2 4 6 8 * ... ... * * * * * * * Fin Show ( trajectoires ) * * * * * * *

CHAPITRE 6. CONSTRUCTION

La dnition dun initiateur dsactive le vricateur. Dans notre cas, temps peut ` e e e a nouveau comporter plus ou moins de valeurs que de colonnes dans traj.
> new( + Class = " Trajectoires " , + temps = c (1 ,2 ,48) , + traj =matrix (1:8 , nrow =2) + ) ~ ~ ~ Trajectoires : initiateur ~ ~ ~ * * * Class Trajectoires , method Show * * * * Temps = [1] 1 2 48 * Traj ( limit ` une matrice 10 x10 ) = e a [ ,1] [ ,2] [ ,3] [ ,4] I1 1 3 5 7 I2 2 4 6 8 * ... ... * * * * * * * Fin Show ( trajectoires ) * * * * * * *

Pour utiliser un initiateur et un vricateur dans le mme objet, il faut donc ape e peler manuellement le vricateur grce ` linstruction validObject. Notre initiateur e a a incluant le vricateur devient : e
> setMethod( + f = " initialize " , + signature = " Trajectoires " , + d e f i n i t i o n = function (. Object , temps , traj ){ + cat ( " ~ ~ ~ ~ ~ Trajectoires : initiateur ~ ~ ~ ~ ~ \ n " )

6.2. LINITIATEUR
+ + + + + + + + + + ) i f ( ! missing ( traj )){ colnames( traj ) <- paste ( " T " , temps , sep = " " ) rownames( traj ) <- paste ( " I " ,1: nrow ( traj ) , sep = " " ) . Object@temps <- temps . Object@traj <- traj validObject (. Object ) } return (. Object ) }

47

[1] " initialize " > new( + Class = " Trajectoires " , + temps = c (1 ,2 ,4 ,8) , + traj =matrix (1:8 , nrow =2) + ) ~ ~ ~ ~ ~ Trajectoires : initiateur ~ ~ ~ ~ ~ ~ ~ ~ Trajectoires : v rificateur ~ ~ ~ e * * * Class Trajectoires , method Show * * * * Temps = [1] 1 2 4 8 * Traj ( limit ` une matrice 10 x10 ) = e a T1 T2 T4 T8 I1 1 3 5 7 I2 2 4 6 8 * ... ... * * * * * * * Fin Show ( trajectoires ) * * * * * * * > new( + Class = " Trajectoires " , + temps = c (1 ,2 ,48) , + traj =matrix (1:8 , nrow =2) + ) ~ ~ ~ ~ ~ Trajectoires : initiateur ~ ~ ~ ~ ~ Error in dimnames ( x ) <- dn : la longueur de ' dimnames ' [2] n ' est pas gale ` l ' tendue du tableau e a e

Cette nouvelle dnition a supprim lancienne. Vous aurez not la condition portant e e e sur missing(traj) pour prendre en compte lobjet vide... Un constructeur ne prend pas ncessairement pour argument les attributs de lobjet. e Par exemple, si on sait (a nest pas le cas dans la ralit, mais imaginons) que lIMC c e e augmente de 0.1 toutes les semaines, on pourrait construire des trajectoires en fournissant le nombre de semaines et les IMC initiaux :
> setClass ( + Class = " TrajectoiresBis " , + representation ( + temps = " numeric " ,

48
+ + + ) traj = " matrix " )

CHAPITRE 6. CONSTRUCTION

[1] " TrajectoiresBis " > setMethod( " initialize " , + " TrajectoiresBis " , + function (. Object , nbSemaine , IMCinit ){ + calculTraj <- function ( init , nbSem ){ + return ( init +0.1 * nbSem ) + } + traj <- outer ( IMCinit ,1: nbSemaine , calculTraj ) + colnames( traj ) <- paste ( " T " ,1: nbSemaine , sep = " " ) + rownames( traj ) <- paste ( " I " ,1: nrow ( traj ) , sep = " " ) + . Object@temps <- 1: nbSemaine + . Object@traj <- traj + return (. Object ) + } + ) [1] " initialize " > new( Class = " TrajectoiresBis " , nbSemaine =4 , IMCinit = c (16 ,17 ,15.6)) An object of class " TrajectoiresBis " Slot " temps " : [1] 1 2 3 4 Slot " traj " : T1 T2 T3 T4 I1 16.1 16.2 16.3 16.4 I2 17.1 17.2 17.3 17.4 I3 15.7 15.8 15.9 16.0

Il ne peut y avoir quun seul initiateur par classe. Il faut donc quil soit le plus gnral possible. La dnition ci-dessus interdirait la construction dune trae e e jectoire ` partir dune matrice. Elle est donc fortement dconseille car trop a e e spcique. Au nal, il vaut mieux laisser ce genre de transformation aux constructeurs e grand public.

6.3

Constructeur grand public

Comme nous lavions dit en introduction, le (gentil) programmeur, ayant conscience du fait que new nest pas une fonction sympathique, ajoute des constructeurs grand public. Cela se fait grce ` une fonction (fonction classique, pas ncessairement une a a e mthode S4) portant gnralement le nom de la classe. Dans notre cas, ca sera la fonction e e e trajectoires.

6.3. CONSTRUCTEUR GRAND PUBLIC

49

> trajectoires <- function ( temps , traj ){ + cat ( " ~ ~ ~ ~ ~ Trajectoires : constructeur ~ ~ ~ ~ ~ \ n " ) + new( Class = " Trajectoires " , temps = temps , traj = traj ) + } > trajectoires ( temps = c (1 ,2 ,4) , traj =matrix (1:6 , ncol =3)) ~ ~ ~ ~ ~ Trajectoires : constructeur ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Trajectoires : initiateur ~ ~ ~ ~ ~ ~ ~ ~ Trajectoires : v rificateur ~ ~ ~ e * * * Class Trajectoires , method Show * * * * Temps = [1] 1 2 4 * Traj ( limit ` une matrice 10 x10 ) = e a T1 T2 T4 I1 1 3 5 I2 2 4 6 * ... ... * * * * * * * Fin Show ( trajectoires ) * * * * * * *

Lintrt est de pouvoir faire un traitement plus sophistiqu. Par exemple, dans un ee e grand nombre de cas, Tam mesure les trajectoires toutes les semaines et elle les stocke dans une matrice. Elle souhaite donc avoir le choix : soit dnir lobjet trajectoires e simplement en donnant une matrice, soit en donnant une matrice et les temps :
> trajectoires <- function ( temps , traj ){ + i f ( missing ( temps )){ temps <- 1: ncol ( traj )} + new( Class = " Trajectoires " , temps = temps , traj = traj ) + } > trajectoires ( traj =matrix (1:8 , ncol =4)) ~ ~ ~ ~ ~ Trajectoires : initiateur ~ ~ ~ ~ ~ ~ ~ ~ Trajectoires : v rificateur ~ ~ ~ e * * * Class Trajectoires , method Show * * * * Temps = [1] 1 2 3 4 * Traj ( limit ` une matrice 10 x10 ) = e a T1 T2 T3 T4 I1 1 3 5 7 I2 2 4 6 8 * ... ... * * * * * * * Fin Show ( trajectoires ) * * * * * * *

R accepte parfois que deux entits direntes portent le mme nom. Dans e e e le cas prsent, il est possible de dnir une fonction portant le mme nom e e e quune classe. Un inconvnient ` cela est quon ne sait plus ensuite de quoi e a on parle. Nous vous conseillons plutt de donner ` la classe un nom avec une majuscule o a et ` la fonction constructeur le mme nom mais avec une minuscule. a e Contrairement ` linitiateur, on peut dnir plusieurs constructeurs. Toujours a e sous lhypoth`se que lIMC augmente de 0.1 toutes les semaines, on peut dnir e e trajectoiresRegulieres :

50

CHAPITRE 6. CONSTRUCTION

> t rajectoiresRegulieres <- function ( nbSemaine , IMCinit ){ + funcInit <- function ( init , nbSem ){ return ( init +0.1 * nbSem )} + traj <- outer ( IMCinit ,1: nbSemaine , funcInit ) + temps <- 1: nbSemaine + return (new( Class = " Trajectoires " , temps = temps , traj = traj )) + } > t rajectoiresRegulieres ( nbSemaine =3 , IMCinit = c (14 ,15 ,16)) ~ ~ ~ ~ ~ Trajectoires : initiateur ~ ~ ~ ~ ~ ~ ~ ~ Trajectoires : v rificateur ~ ~ ~ e * * * Class Trajectoires , method Show * * * * Temps = [1] 1 2 3 * Traj ( limit ` une matrice 10 x10 ) = e a T1 T2 T3 I1 14.1 14.2 14.3 I2 15.1 15.2 15.3 I3 16.1 16.2 16.3 * ... ... * * * * * * * Fin Show ( trajectoires ) * * * * * * *

Ainsi, les deux constructeurs font tous les deux appel ` linitiateur. Do` limportance a u dun initiateur gnraliste. e e

6.4

Petit bilan

Lors de la construction dun objet, il y a donc trois endroits o` il est possible defu fectuer des oprations : dans la fonction de construction, dans linitiateur et dans le ve e ricateur. Le vricateur ne peut faire que vrier, il ne permet pas de modier lobjet. e e Par contre, on peut lappeler sur un objet dj` construit. Pour ne pas trop se mlanger, ea e il est donc prfrable de spcialiser chacun de ces oprateurs et de lui rserver certaines ee e e e tches prcises : a e La fonction de construction est celle qui sera appele par lutilisateur. Elle e est la plus gnrale et peut prendre des arguments variables, ventuellement des e e e arguments qui ne sont pas des attributs de lobjet. Elle transforme ensuite ses arguments en des attributs. Nous conseillons donc de lui coner la transformation de ses arguments en futurs attributs (comme trajectoiresRegulieres a prpar e e des arguments pour new("Trajectoires")). La fonction de construction se termine toujours par new. Linitiateur est appel par new. Il est charg de donner ` chaque attribut sa e e a valeur, apr`s modication ventuelle. On peut le charger des tches qui doivent e e a tre eectues pour tous les objets, quels que soit les constructeurs qui les appellent e e (comme le renommage des lignes et des colonnes de Trajectoires). Si linitiateur na pas t dni, R appelle un initiateur par dfaut qui se contente ee e e daecter les valeurs aux attributs puis dappeler le validateur. Au nal, linitiateur doit appeler le vricateur (linitiateur par dfaut appelle le e e vricateur, linitiateur dni par lutilisateur doit faire un appel explicite). e e

6.4. PETIT BILAN

51

Le vricateur contrle la cohrence interne de lobjet. Il peut par exemple e o e interdire certaines valeurs ` certains attributs, vrier que la taille de attributs est a e conforme ` ce qui est attendu,... Il ne peut pas modier les valeurs des attributs, a il doit se contenter de vrier quils suivent des r`gles. e e Ce dcoupage des tches a pour avantage de bien sparer les choses. Par contre, il e a e nest pas le meilleur en terme decacit: e En eet, prcise un relecteur, linitiateur par dfaut de R est bien plus ecace que e e les initiateurs crits par les programmeurs. Il est donc intressant de lutiliser. Pour cela, e e il sut de ne pas le dnir. Dans cette optique : e Le constructeur fait tout le travail prparatoire. e Linitiateur nest pas dni pas lutilisateur. Cest donc linitiateur par dfaut qui e e est appel. e Le vricateur contrle la cohrence interne de lobjet. e o e Cette mani`re de faire, un tout petit peu moins claire pour le dbutant, est plus e e ecace par la suite. Pour le nophyte, savoir quelle mthode est appele, et quand, est un vrai cassee e e tte. new utilise linitiateur sil existe, le vricateur sinon (mais pas les deux sauf appel e e explicite, ce que nous avons fait). Dautres instructions, comme as (section 9.8 page 77) font appel aux initiateurs et vricateurs. Dans le doute, pour bien comprendre qui e est appel et quand, nous avons ajout une petite ligne en tte de fonction qui ache le e e e nom de la mthode utilise. Top moche ont comment certains relecteurs. Hlas, ils ont e e e e raison. Mais la pdagogie prime ici sur lesthtique... Dailleurs, quand nous en serons ` e e a lhritage, les choses deviendront un peu plus compliques et cet achage top moche e e sera un peu plus ncessaire... e

52

CHAPITRE 6. CONSTRUCTION

Chapitre 7

Accesseur
Nous en avons dj` parl, utiliser @ en dehors dune mthode est fortement dconea e e e seill... Pourtant, il est ncessaire de pouvoir rcuprer les valeurs des attributs. Cest e e e e le rle des accesseurs. Dans la langue de Moli`re, on les appelle les selecteurs et les o e aectants. En franais option informatique, on parle plutt de getteurs et setteurs, franc o cisation de get et set.

7.1

Les getteurs

Un getteur est une mthode qui renvoie la valeur dun attribut. En programmation e classique, un grand nombre de fonctions prennent une variable et retournent une partie de ces arguments. Par exemple, names appliqu ` un data.frame retourne les noms des ea colonnes ; nrow appliqu au mme data.frame donne le nombre de lignes. Et ainsi de e e suite. Pour nos trajectoires, nous pouvons dnir plusieurs getteurs : bien sr, il nous en e u faut un qui renvoie temps et un qui renvoie traj. Nos getteurs tant des mthodes e e nouvelles pour R, il faut les dclarer grce ` setGeneric puis les dnir simplement e a a e grce ` un setMethod : a a
> # ## Getteur pour temps ' > setGeneric ( " getTemps " , + function ( object ){ standardGeneric ( " getTemps " )} + ) [1] " getTemps " > setMethod( " getTemps " ," Trajectoires " , + function ( object ){ + return ( object@temps ) + } + ) [1] " getTemps "

53

54

CHAPITRE 7. ACCESSEUR

> getTemps ( trajCochin ) [1] 1 2 4 5 > # ## Getteur pour traj ' > setGeneric ( " getTraj " , + function ( object ){ standardGeneric ( " getTraj " )} + ) [1] " getTraj " > setMethod( " getTraj " ," Trajectoires " , + function ( object ){ + return ( object@traj ) + } + ) [1] " getTraj " > getTraj ( trajCochin ) [ ,1] 15.0 16.0 15.2 15.7 [ ,2] 15.1 15.9 NA 15.6 [ ,3] 15.2 16.0 15.3 15.8 [ ,4] 15.2 16.4 15.3 16.0

[1 ,] [2 ,] [3 ,] [4 ,]

Mais on peut aussi faire des getteurs plus labors. Par exemple, on peut avoir rgue e e li`rement besoin de lIMC au temps dinclusion : e
> > > + + # ## Getteur pour les IMC ` l ' inclusion a # ## ( premi` re colonne de traj ' ) e setGeneric ( " getTrajInclusion " , function ( object ){ standardGeneric ( " getTrajInclusion " )} )

[1] " getTrajInclusion " > setMethod( " getTrajInclusion " ," Trajectoires " , + function ( object ){ + return ( object@traj [ ,1]) + } + ) [1] " getTrajInclusion " > getTrajInclusion ( trajCochin ) [1] 15.0 16.0 15.2 15.7

7.2. LES SETTEURS

55

7.2

Les setteurs

Un setteur est une mthode qui aecte une valeur ` un attribut. Sous R, laectation e a est faite par <-. Sans entrer dans les mandres du programme, loprateur <- fait en e e ralit appel ` une mthode spcique. Par exemple, quand on utilise names(data) <e e a e e "A", R fait appel ` la fonction names<-. Cette fonction duplique lobjet data, modie a lattribut names de ce nouvel objet puis remplace data par ce nouvel objet. Nous allons faire pareil pour les attributs de nos trajectoires. setTemps<- permettra de modier lattribut temps. Pour cela, on utilise la fonction setReplaceMethod
> setGeneric ( " setTemps <-" , + function ( object , value ){ standardGeneric ( " setTemps <-" )} + ) [1] " setTemps <-" > setReplaceMethod( + f = " setTemps " , + signature = " Trajectoires " , + d e f i n i t i o n = function ( object , value ){ + object@temps <- value + return ( object ) + } + ) [1] " setTemps <-" > ( setTemps ( trajCochin ) <- 1:3) [1] 1 2 3

Tout lintrt du setteur est de pouvoir faire des contrles. Comme dans initialize, ee o nous pouvons appeler explicitement le vricateur : e
> setReplaceMethod( + f = " setTemps " , + signature = " Trajectoires " , + d e f i n i t i o n = function ( object , value ){ + object@temps <- value + validObject ( object ) + return ( object ) + } + ) [1] " setTemps <-" > setTemps ( trajCochin ) <- c (1 ,2 ,4 ,6) ~ ~ ~ Trajectoires : v rificateur ~ ~ ~ e > setTemps ( trajCochin ) <- 1:4

56

CHAPITRE 7. ACCESSEUR

~ ~ ~ Trajectoires : v rificateur ~ ~ ~ e Error in validityMethod ( object ) : [ Trajectoire : validation ] Le nombre de mesures temporelles ne correspond pas au nombre de colonnes de la matrice

7.3

Les oprateurs [ et [<e

Il est galement possible de dnir les getteurs grce ` loprateur [ et les setteurs e e a a e grce ` [<-. Cela se fait comme pour une mthode quelconque en prcisant la classe et a a e e la fonction ` appliquer. Cette fonction prend quatre arguments : a x est lobjet. i dsigne lattribut auquel nous voulons accder. e e Si lattribut dsign par i est complexe (une matrice, une liste,...), j permet dace e cder ` un lment particulier. e a ee Enn, drop est un bolen permettant de prciser si ce qui est retourn doit garder e e e sa structure initiale ou non (par exemple si une matrice dune seule ligne doit tre e considr comme un vecteur ou comme une matrice). ee Dans notre exemple, [ peut simplement retourner lattribut correspondant ` i. a
> setMethod( + f ="[", + signature = " Trajectoires " , + d e f i n i t i o n = function (x ,i ,j , drop ){ + switch ( EXPR =i , + " temps " ={ return ( x@temps )} , + " traj " ={ return ( x@traj )} + ) + } + ) [1] " [ "

Ensuite, lappel de la fonction [ se fait sous la forme x[i="Attribut1", j=3, drop=FALSE], ou sous la forme simplie x["Attribut1",3,FALSE]. Dans notre cas, e j et drop ntant pas utiliss, on peut simplement les omettre : e e
> trajCochin [ i = " temps " ] [1] 1 2 4 6 > trajCochin [ " traj " ] [ ,1] [ ,2] [ ,3] [ ,4] [1 ,] 15.0 15.1 15.2 15.2 [2 ,] 16.0 15.9 16.0 16.4

7.3. LES OPERATEURS [ ET [<[3 ,] 15.2 NA 15.3 15.3 [4 ,] 15.7 15.6 15.8 16.0

57

La dnition que nous venons dcrire nore aucune protection contre les erreurs e e typographiques :
> trajCochin [ " trak " ] NULL

Il est donc important de nir lnumration par le comportement ` adopter quand e e a lattribut nexiste pas :
> setMethod( + f ="[", + signature = " Trajectoires " , + d e f i n i t i o n = function (x ,i ,j , drop ){ + switch ( EXPR =i , + " temps " ={ return ( x@temps )} , + " traj " ={ return ( x@traj )} , + stop ( " Cet attribut n ' existe pas ! " ) + ) + + } + ) [1] " [ "

Nous sommes maintenant ` labri dune erreur de typographie. a drop est un argument ` utiliser avec prcaution. En eet, il a pour vocation a e de modier le type de lobjet. Par exemple, si M est une matrice, quel est le type de M[,b] ? Cela dpend de b. Si b est un vecteur, alors M[,b] est une e matrice. Si b est un entier, alors M[,b] est un vecteur... Comme toujours, un comportement qui dpend est ` proscrire. e a Les setteurs se dnissent selon le mme principe grce ` loprateur [<-. On utilise e e a a e setReplaceMethod. L` encore, une fonction dcrit le comportement ` adopter. L` encore, a e a a il est important de veiller ` contrler une ventuelle faute de frappe. : a o e
> setReplaceMethod( + f ="[", + signature = " Trajectoires " , + d e f i n i t i o n = function (x ,i ,j , value ){ + switch ( EXPR =i , + " temps " ={ x@temps <- value } , + " traj " ={ x@traj <- value } , + stop ( " Cet attribut n ' existe pas ! " ) + ) + validObject ( x ) + return ( x ) + } + )

58

CHAPITRE 7. ACCESSEUR

[1] " [ <-" > trajCochin [ " temps " ] <- 2:5 ~ ~ ~ Trajectoires : v rificateur ~ ~ ~ e

Dans nos dnitions de [ et [<-, nous avons list les dirents attributs e e e possibles pour i (i=="temps" et i=="traj"). Il serait galement possible de e les numroter (i==1 et i==2). Lacc`s au premier attribut se ferait alors via e e trajCochin[1] ` la place de trajCochin["temps"]. Cest bien videmment totalement a e impropre : on se mettrait ` la merci de lerreur typographique trajCochin[2] ` la place a a de trajCochin[1] (alors que trajCochin["trmps"] ne prsente pas de danger puisquil e propovoque une erreur).

7.4

[, @ ou get ?

Quand doit-on utiliser get, quand doit-on utiliser @, quand doit-on utiliser [ ? @ est ` rserver exclusivement aux mthodes internes ` la classe : si une mthode de a e e a e partition Partition a besoin de traj (cest ` dire dun attribut dune autre classe), il a lui est formellement interdit dutiliser @ pour accder aux attributs directement, elle doit e passer par [ ou par get. A lintrieur dune classe (si une mthode de Partition a besoin de nbCluster), il e e y a deux coles : ceux qui utilisent @ et ceux qui utilisent [ (ou get). e Entre get et [, il ny a pas vraiment de dirence, cest simplement un jeu dcriture : e e getTemps(trajCochin) ou trajCochin["temps"] ? La premi`re notation rappelle les e autres langages objets, la deuxi`me est plus spcique ` R. Dans le cas dun package e e a et donc de mthodes qui ont pour vocation dtre utilises par dautres, [ sera plus e e e conforme ` la syntaxe classique de R, donc plus intuitif. a

Troisi`me partie e

Pour aller plus loin

59

61 La suite comprend les signatures, lhritage et quelques autres concepts avancs. Si e e vous tes vraiment novice en programmation objet, il est peut-tre temps de faire une e e petite pause pour intgrer ce qui vient dtre prsent. Ce que nous venons de voir sut e e e e largement ` faire quelques petites classes. Vos dicults vous permettront entre autres a e de mieux comprendre le pourquoi de ce qui va suivre...

62

Chapitre 8

Mthodes utilisant plusieurs e arguments


Nous avons fait notre premier objet. La suite est plus lie aux interactions entre les e objets. Il est donc temps de dnir nos deux autres objets. En premier lieu, Partition. e

8.1

Le probl`me e

Ceci est un manuel. Nous nallons donc pas dnir partition et le cort`ge de mthodes e e e qui accompagne chaque nouvelle classe mais simplement ce dont nous avons besoin :
> setClass ( + Class = " Partition " , + representation = representation ( + nbGroupes = " numeric " , + part = " factor " + ) + ) [1] " Partition " > setMethod( f = " [ " , signature = " Partition " , + d e f i n i t i o n = function (x ,i ,j , drop ){ + switch ( EXPR =i , + " part " ={ return ( x@part )} , + " nbGroupes " ={ return ( x@nbGroupes )} , + stop ( " Cet attribut n ' existe pas ! " ) + ) + + } + ) [1] " [ " > partCochin <- new( Class = " Partition " , nbGroupes =2 , + part = f a c t o r ( c ( " A " ," B " ," A " ," B " ))

63

64

CHAPITRE 8. METHODES UTILISANT PLUSIEURS ARGUMENTS

+ ) > partStAnne <- new( Class = " Partition " , nbGroupes =2 , + part = f a c t o r ( rep ( c ( " A " ," B " ) , c (50 ,30))) + )

Nous supposerons de plus que part est toujours compos de lettres majuscules allant e de A ` LETTERS[nbGroupes] (il faudra bien prciser dans la documentation de cette classe a e que le nombre de groupes doit tre infrieur ` 26). Nous pouvons nous permettre une e e a telle supposition en programmant initialize et part<- de mani`re ` toujours vrier e a e que cest le cas. Nous avons donc un objet trajCochin de classe Trajectoires et un dcoupage e de cet objet en un objet partCochin de classe Partition. Lorsque nous reprsentons e trajCochin graphiquement, nous obtenons un faisceau de courbes multicolores. Maintenant que les trajectoires sont associes ` des groupes, il serait intressant de dessiner e a e les courbes en donnant une couleur ` chaque groupe. Pour cela, il va falloir dnir a e une mthode plot qui prendra comme argument un objet Trajectoires plus un objet e Partition. Cest possible grce ` lutilisation de signature. a a

8.2

signature

La signature, nous lavons dj` vu lors de la dnition de nos premi`res mea e e e thodes section 5.1 page 35, est le deuxi`me argument fourni ` setMethod. Jusqu` e a a prsent, nous utilisions des signatures simples constitues dune seule classe. Dans e e setMethod(f="plot",signature="Trajectoires",definition=function), la signature est simplement "Trajectoires" Pour avoir des fonctions dont le comportement dpend de plusieurs objets, il est e possible de dnir un vecteur signature comportant plusieurs classes. Ensuite, quand nous e appelons une mthode, R cherche la signature qui lui correspond le mieux et applique e la fonction correspondante. Un petit exemple simpose. Nous allons dnir une fonction e essai
> setGeneric ( " essai " , function (x ,y ,...){ standardGeneric ( " essai " )}) [1] " essai "

Cette fonction a pour mission dadopter un certain comportement si son argument est numeric, un autre comportement si sest un character.
> setMethod( + f = " essai " , + signature = " numeric " , + function (x ,y ,...){ cat ( " x est un numeric = " ,x , " \ n " )} + ) [1] " essai "

A ce stade, essai sait acher les numeric, mais ne sait pas acher les character :

8.2. SIGNATURE

65

> # ## 3.17 tant un numeric , R va applique la methode e > # ## essai pour les numeric > essai (3.17) x est un numeric = > essai ( " E " ) Error in function ( classes , fdef , mtable ) : unable to find an inherited method for function " essai " , for signature " character " 3.17

Pour que essai soit compatible avec les character, il faut dnir la mthode avec e e la signature character :
> setMethod( + f = " essai " , + signature = " character " , + function (x ,y ,...){ cat ( " x est character = " ,x , " \ n " )} + ) [1] " essai " > # ## ' E ' tant un character , R applique maintenant la m thode e e > # ## essai pour les characters > essai ( " E " ) x est character = E

Plus compliqu, nous souhaitons que essai ait un comportement dirent si on e e combine un numeric et un character.
> # ## Pour une m thode qui combine numeric et character : e > setMethod( + f = " essai " , + signature = c ( x = " numeric " ,y = " character " ) , + d e f i n i t i o n = function (x ,y ,...){ + cat ( " Plus compliqu : " ) e + cat ( " x est un num = " ,x , " ET y un est un char = " ,y , " \ n " ) + } + ) [1] " essai "

Maintenant, R connait trois mthodes ` appliquer ` essai : la premi`re est applique e a a e e si largument de essai est un numeric ; la deuxi`me est applique si largument de essai e e est un character ; la troisi`me est applique si essai a deux arguments, un numeric e e puis un character
> essai (3.2 , " E " ) Plus compliqu : x est un num = 3.2 e ET y un est un char = E

66

CHAPITRE 8. METHODES UTILISANT PLUSIEURS ARGUMENTS

> essai (3.2) x est un numeric = > essai ( " E " ) x est character = E 3.2

Retour ` miniKml (le package que nous sommes en train de construire). De la mme a e mani`re, nous avions dni plot pour la signature Trajectoires, nous allons maintenant e e dnir plot pour la signature c("Trajectoires","Partition"). Nous pourrons ensuite e reprsenter graphiquement les trajectoires selon des partitions spciques. e e
> setMethod( + f = " plot " , + signature = c ( x = " Trajectoires " ,y = " Partition " ) , + d e f i n i t i o n = function (x ,y ,...){ + matplot( x@temps , t ( x@traj [ y@part == " A " ,]) , + ylim = range ( x@traj , na . rm =TRUE) , + xaxt = " n " , type = " l " , ylab = " " , xlab = " " , col =2 + ) + f o r ( i in 2: y@nbGroupes ){ + matlines ( x@temps , t ( x@traj [ y@part == LETTERS [ i ] ,]) , + xaxt = " n " , type = " l " , col = i +1 + ) + } + a x i s (1 , at = x@temps ) + } + ) [1] " plot " > # ## Plot pour Trajectoire ' > plot ( trajCochin ) > plot ( trajStAnne ) EMPTY
16.2 19 2 3 4 5 16 15.0 1 17 15.4 18 15.8

12

16

20

24

EMPTY

8.3. MISSING

67

> # ## Plot pour Trajectoire ' et > plot ( trajCochin , partCochin ) > plot ( trajStAnne , partStAnne ) EMPTY
16.2

Partition '

15.8

15.4

15.0

16 1

17

18

19

12

16

20

24

EMPTY

Plutt lgant, nest-il pas ? o ee

8.3

missing

Il est galement possible de dnir une mthode ayant un certain comportement si e e e elle a un unique argument, un autre comportement si elle en a plusieurs. Cela est possible grce ` missing. missing est vrai si largument est manquant : a a
> setMethod( + f = " essai " , + signature = c ( x = " numeric " ,y = " missing " ) , + d e f i n i t i o n = function (x ,y ,...){ + cat ( " x est numeric = " ,x , " et y est + } + ) [1] " essai " > # ## M thode sans y donc utilisant le missing e > essai (3.17) x est numeric = 3.17 et y est missing '

missing ' \ n " )

> # ## Methode avec y = ' character ' > essai (3.17 , " E " ) Plus compliqu : x est un num = 3.17 e ET y un est un char = E

68

CHAPITRE 8. METHODES UTILISANT PLUSIEURS ARGUMENTS

8.4

Nombre darguments dune signature

Sans entrer dans les mandres internes de R, quelques petites r`gles concernant les e e signatures : une signature doit comporter autant darguments que sa mthode gnrique, e e e ni plus, ni moins. Cela signie quil nest pas possible de dnir une mthode pour print e e qui prendra en compte deux arguments puisque print a pour signature x. De mme, e plot ne peut tre dni que pour deux arguments, impossible den prciser un troisi`me e e e e dans la signature.

8.5

ANY

Rciproquement, la signature doit comporter tous les arguments. Jusqu` prsent, e a e nous ne nous en sommes pas souci et nous avons dni des plot avec un seul argument. e e Cest simplement une facilit dcriture : R est pass derni`re nous et a ajout le deuxi`me e e e e e e argument. Comme nous navions pas prcis le type de ce deuxi`me argument, il en a e e e conclu que la mthode devait sappliquer quel que soit le type du deuxi`me argument. e e Pour le dclarer explicitement, il existe un argument spcial, la classe originelle, la cause e e premi`re : ANY (plus de dtail sur ANY section 9.2 page 70). Donc, quand nous omettons e e un argument, R lui donne pour nom ANY. La fonction showMethods, la mme qui nous permettait de voir les toutes les mthodes e e existant pour un objet section 5.4 page 41, permet dacher la liste des signatures que R connait pour une certaine mthode : e
> showMethods( essai ) Function : essai ( package . GlobalEnv ) x = " character " , y = " ANY " x = " numeric " , y = " ANY " x = " numeric " , y = " character " x = " numeric " , y = " missing "

Comme vous pouvez le constater, la liste ne contient pas les signatures que nous avons dnies, mais des signatures compltes : les arguments que nous navions pas e ee prciss (` savoir y dans les cas x="character" et x="numeric") ont t remplacs par e e a ee e "ANY". Plus prcisment, ANY nest utilis que si aucun argument autre ne convient. Dans e e e le cas de essai, si x est un numeric, R hsite entre trois mthodes. En premier lieu, e e il essaie de voir si y a un type dni par ailleurs. Si y est un character, la mthode e e utilise sera celle correspondant ` (x="numeric",y="character"). Si y nest pas un e a character, R ne trouve pas de correspondance exacte entre y et un type, il utilise donc la mthode fourre-tout : x="numeric", y="ANY". e

Chapitre 9

Hritage e
Lhritage est lun des concepts clefs de la programmation objet. Il permet de rutilie e ser des pans entiers de programme ` peu de frais. Dans notre cas, nous devons maintenant a dnir TrajDecoupees. Il va nous falloir coder lobjet, les constructeurs, les setteurs et e le getteurs, lachage... Tout. Les plus astucieux dentre nous sont dj` en train de ea se dire quil sura de faire un copier-coller de mthodes cres pour Trajectoires et e ee de les adapter. La programmation objet permet de faire mieux : nous allons dnir e TrajDecoupees comme objet hritier de Trajectoires. e

9.1

Principe

Lhritage est un principe de programmation permettant de crer une nouvelle classe e e a ` partir dune classe dj` existante, la nouvelle classe tant une spcialisation de la ea e e prcdente. On dit de la nouvelle classe quelle hrite de la classe ` partir de laquelle elle e e e a est dnie. La nouvelle classe sappelle donc classe ls alors que la classe ayant servi ` e a la cration est la classe p`re. e e Plus prcisment, la classe ls est une spcialisation de la classe p`re dans le sens o` e e e e u elle peut faire tout ce que fait la classe p`re plus de nouvelles choses. Prenons un exemple, e classique en programmation objet. La classe Vehicule est dnie comme comprenant e un attribut vitesse et une mthode tempsDeParcours, une mthode qui permet de e e calculer le temps mis pour parcourir une certaine distance. Cest donc une classe assez gnrale comprenant tout type de vhicule, de la trottinette au ptrolier. e e e e On souhaite maintenant dnir la classe Voiture. Cette classe peut tre considre e e ee comme un vhicule particulier. On peut donc dnir Voiture comme classe hriti`re de e e e e Vehicule. Un objet Voiture aura les mmes arributs et mthodes que Vehicule, plus e e des attributs et mthodes propres comme NombreDePortes. Cet attribut fait sens pour e une voiture, mais ferait bien moins de sens pour le concept de vhicule au sens large du e terme (parce quil serait ridicule de parler de portes pour une trottinette). Formellement, une classe Fils peut hriter dune classe Pere quand Fils contient e au moins tous les attributs de Pere (plus ventuellement dautres). Le fait dhriter e e rend toutes les mthodes de Pere disponibles pour Fils : chaque fois quon utilisera e 69

70

CHAPITRE 9. HERITAGE

une mthode sur un objet de classe Fils, R cherchera si cette mthode existe. Sil ne la e e trouve pas dans la liste des mthodes spciques ` Fils, il cherchera dans les mthodes e e a e de Pere. Sil la trouve, il lappliquera. Sil ne la trouve pas, il cherchera dans les mthodes e dont Pere hrite. Et ainsi de suite. e On reprsente le lien qui unit le p`re et le ls par une `che allant du ls vers le p`re. e e e e Cela symbolise que lorsquune mthode nest pas trouve pour le ls, R suit la `che e e e et cherche dans les mthodes du p`re : classPere classFils ou encore : e e Vehicule Voiture On note classiquement le p`re ` gauche du ls (ou au dessus) puisquil est dni e a e avant.

9.2

P`re, grand-p`re et ANY e e

Nous venons de le voir, quand R ne trouve pas une mthode pour un objet, le principe e de lhritage lui demande de chercher parmi les mthodes du p`re. Le principe est rcursif. e e e e Sil ne trouve pas chez le p`re, il cherche chez le grand-p`re, et ainsi de suite. Sur e e notre exemple, nous pourrions considrerer une classe de voiture particuli`re, les voitures e e sportives. Vehicule Voiture Sportive Si R ne trouve pas une mthode pour Sportive, il cherche parmi celle de Voiture. e Sil ne trouve pas dans Voiture, il cherche dans Vehicule et ainsi de suite. Se pose alors la question de lorigine, de lanctre ultime, la racine des racines. Chez les hommes, e cest -selon certaines sources non vries- Adam. Chez les objets, cest ANY. ANY est la e e classe premi`re, celle dont toutes les autres hritent. Une classe cre de toute pi`ce sans e e ee e que le programmeur ne la dnisse comme hriti`re ` partir dune autre (comme toutes e e e a celles que nous avons cres dans les chapitres prcdents) est considre par R comme ee e e ee hriti`re de ANY. Donc, si une mthode nest pas trouve pour une classe Fils, elle sera e e e e cherche dans la classe Pere, puis GrandPere et ainsi de suite. Si elle nest pas trouve e e parmi les anctres (ou si Fils na pas de p`re), elle sera cherche dans la classe ANY. Si e e e elle nexiste pas pour ANY, une erreur est ache. e

9.3

contains

Nous allons donc dnir TrajDecoupees comme hriti`re de Trajectoires. Pour e e e cela, on dclare lobjet en ajoutant largument contains suivi du nom de la classe p`re. e e
> setClass ( + Class = " TrajDecoupees " , + representation = representation ( listePartitions = " list " ) , + contains = " Trajectoires " + )

9.4. UNCLASS

71

~ ~ ~ ~ ~ Trajectoires : initiateur ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Trajectoires : initiateur ~ ~ ~ ~ ~ [1] " TrajDecoupees " > tdPitie <- new( " TrajDecoupees " ) ~ ~ ~ ~ ~ Trajectoires : initiateur ~ ~ ~ ~ ~

9.4

unclass

TrajDecoupees contient donc tous les attributs de Trajectoires plus son attribut personnel listePartitions (attribut qui contiendra une liste de partition). Pour linstant, il nest pas possible de le vrier directement. En eet, si nous essayons e de voir tdCochin, nous obtenons lachaqe dun objet Trajectoires, et non pas une TrajDecoupees.
> tdPitie * * * Class Trajectoires , method Show * * * * Temps = numeric (0) * Traj ( limit ` une matrice 10 x10 ) = e a * ... ... * * * * * * * Fin Show ( trajectoires ) * * * * * * *

Voil` qui appelle quelques commentaires : TrajDecoupees est un hritier de a e Trajectoires. A chaque fois quune fonction est appele, R cherche cette fonction pour e la signature TrajDecoupees. Sil ne trouve pas, il cherche la fonction pour la classe parent ` savoir Trajectoires. Sil ne trouve pas, il cherche dans les fonctions de ANY, cest a a ` dire les fonctions par dfaut. e Voir un objet se fait grce ` show. Comme ` ce stade show nexiste pas pour a a a TrajDecoupees, cest show pour Trajectoires qui est appel ` la place. Taper tdPitie ea ne nous montre donc pas lobjet tel quil est rellement mais via le prisme show pour e Trajectoires. Il est donc urgent de dnir une mthode show pour les TrajDecoupees. e e Nanmoins, il serait intressant de pouvoir jeter un oeil ` lobjet que nous venons de e e a crer. On peut pour cela utiliser unclass. unclass fait comme si un objet avait pour e classe ANY. unclass(tdPitie) va donc appeler la mthode show comme si tdPitie e avait pour classe ANY, et va donc utiliser la mthode show par dfaut. Rsultat, lobjet e e e est ach sans oritures, certes, mais dans son intgralit. e e e
> unclass ( tdPitie ) < S4 Type Object > attr ( , " listePartitions " ) list () attr ( , " temps " ) numeric (0) attr ( , " traj " ) <0 x 0 matrix >

72

CHAPITRE 9. HERITAGE Lobjet comporte donc eectivement les attributs de Trajectoires plus une liste.

9.5

Arbre dhritage e

Plusieurs classes peuvent hriter dun mme p`re. Au nal, la reprsentation grae e e e phique des liens unissant les classes donne un arbre (un arbre informatique, dsol pour e e les po`tes qui espraient un peu de verdure dans cet ouvrage) : e e

Il est thoriquement possible dhriter de plusieurs p`res. La reprsentation e e e e graphique nest alors plus un arbre mais un graphe. Mal utilise, cette prae tique peut tre dangereuse. En eet, supposons quun objet B hrite ` la fois e e a de A1 et A2. Si une mthode nexistant pas pour B est appele, elle sera recherche dans e e e les mthodes des p`res. Si la mthode existe pour A1 ET pour A2, laquelle sera utilise, e e e e celle de A1 ou celle de A2 ? L` rside une source de confusion. Cest encore plus probla e e matique pour lutilisation de callNextMethod (voir 9.7 page 75). Pourtant, dans certains cas, lhritage multiple semble plein de bon sens. Prenons e un exemple : la classe machineDeCalcul dispose de mthodes donnant la prcision dun e e calcul. La classe plastic prcise les proprits physiques du plastique, par exemple ce qui e ee se passe quand il brle, sa rsistance... un ordinateur est ` la fois une machineDeCalcul u e a et outil en plastic. Il est donc intressant quil acc`de ` la fois ` la mthode precision e e a a e (pour savoir ce quon peut lui demander) et ` la mthode brulle pour savoir comment a e il ragira dans un incendie. La classe ordinateur pourrait donc lgitimement hriter de e e e deux p`res. e Donc, lhritage multiple est ` manier avec prcaution : il peut tre utile, mais il faut e a e e prendre garde ` ce quune classe nhrite jamais de p`res ayant des mthodes communes. a e e e

9.6

Voir la mthode en autorisant lhritage e e

Lhritage est une force mais il peut tre droutant. Crons un deuxi`me objet e e e e e TrajDecoupees :
> partCochin2 <- new( " Partition " , nbGroupes =3 , + part = f a c t o r ( c ( " A " ," C " ," C " ," B " )) + ) > tdCochin <- new( + Class = " TrajDecoupees " ,

9.6. VOIR LA METHODE EN AUTORISANT LHERITAGE


+ + + + ) temps = c (1 ,3 ,4 ,5) , traj = trajCochin@traj , listePartitions = list ( partCochin , partCochin2 )

73

Error in . local (. Object , ...) : argument ( s ) inutilis ( s ) e ( listePartitions = list ( < S4 object of class " Partition " >, < S4 object of class " Partition " >))

Ca ne marche pas... Pourquoi ? Pour le savoir, il est possible dacher la mthode e initialize appele par new : e
> getMethod( " initialize " ," TrajDecoupees " ) Error in getMethod ( " initialize " , " TrajDecoupees " ) : No method found for function " initialize " and signature TrajDecoupees

L` encore, a ne marche pas, mais cette fois la cause est plus simple ` identier : a c a nous navons pas encore dni initialize pour Partition. e
> existsMethod ( " initialize " ," TrajDecoupees " ) [1] FALSE

Voil` conrmation de nos doutes. Pourtant, R semble tout de mme excuter un code a e e puisquil dtecte une erreur. Mais que se passe-t-il donc 1 ? e Cest un des eets indsirables de lhritage, une sorte dhritage involontaire. e e e En eet, ` lappel de new("TrajDecoupees"), new cherche la fonction initialize a pour TrajDecoupees. Comme il ne la trouve pas ET que TrajDecoupees hrite de e Trajectoires, il remplace la mthode manquante par initialize pour Trajectoires. e Pour vrier cela, deux mthodes : hasMethods permet de savoir si une mthode e e e existe pour une classe donne en prenant en compte lhritage. Pour mmoire, quand e e e existsMethod ne trouvait pas une mthode, elle renvoyait faux. Quand hasMethod ne e trouve pas, elle cherche chez le p`re, puis chez le grand-p`re et ainsi de suite : e e
> hasMethod ( " initialize " ," TrajDecoupees " ) [1] TRUE

Conrmation, new ne repart pas bredouille, il est eectivement rorient vers une me e e thode hrite. Pour acher la mthode en question, on peut utiliser selectMethod. e e e selectMethod a globalement le mme comportement que getMethod. Seule dirence, e e lorsquil ne trouve pas une mthode, il cherche chez les anctres... e e
> selectMethod ( " initialize " ," TrajDecoupees " ) 1. Vous noterez au passage tous les trsors dimagination dvelopps par lauteur pour mnager du e e e e suspense dans un livre de statistique-informatique...

74

CHAPITRE 9. HERITAGE

Method Definition : function (. Object , ...) { . local <- function (. Object , temps , traj ) { cat ( " ~ ~ ~ ~ ~ Trajectoires : initiateur ~ ~ ~ ~ ~ \ n " ) if ( ! missing ( traj )) { colnames ( traj ) <- paste ( " T " , temps , sep = " " ) rownames ( traj ) <- paste ( " I " , 1: nrow ( traj ) , sep = " " ) . Object@temps <- temps . Object@traj <- traj validObject (. Object ) } return (. Object ) } . local (. Object , ...) } Signatures : . Object target " TrajDecoupees " defined " Trajectoires "

Notre hypoth`se tait la bonne, TrajDecoupees utilise linitiateur de Partition. e e Comme ce dernier ne connait pas lattribut listePartitions, il retourne une erreur. Le myst`re est maintenant clairci. e e Pour pouvoir dnir des objets TrajDecoupees un peu plus complexes, il faut donc e au pralable dnir initialize pour TrajDecoupees e e
> + + + + + + + + + + + + setMethod( " initialize " ," TrajDecoupees " , function (. Object , temps , traj , listePartitions ){ cat ( " ~ ~ ~ ~ TrajDecoupees : initiateur ~ ~ ~ ~ \ n " ) i f ( ! missing ( traj )){ . Object@temps <- temps # Affectation des attributs . Object@traj <- traj . Object@listePartitions <- listePartitions } # return de l ' objet return (. Object ) } )

[1] " initialize " > tdCochin <- new( + Class = " TrajDecoupees " , + traj = trajCochin@traj , + temps = c (1 ,3 ,4 ,5) , + listePartitions = list ( partCochin , partCochin2 )

9.7. CALLNEXTMETHOD
+ ) ~ ~ ~ ~ TrajDecoupees : initiateur ~ ~ ~ ~

75

Et voil` ! a

9.7

callNextMethod

Nous venons de le voir : lorsquil ne trouve pas une mthode, R dispose dun me e canisme lui permettant de la remplacer par une mthode hrite. Il est possible de e e e contrler ce mcanisme et de forcer une mthode ` appeler la mthode hrite. Ca pero e e a e e e met entre autre chose de r-utiliser du code sans avoir ` le retaper. Cela se fait grce ` e a a a callNextMethod. callNextMethod nest utilisable que dans une mthode. Elle a pour e eet dappeler la mthode qui serait utilise si la mthode actuelle nexistait pas. Par e e e exemple, considrons la mthode print pour TrajDecoupees. Actuellement, cette me e e thode nexiste pas. Pourtant, un appel a print(tdCochin) serait quand mme excut e e e grce ` lhritage : a a e
> print ( tdCochin ) * * * Class Trajectoires , method Print * * * * Temps = [1] 1 3 4 5 * Traj = [ ,1] [ ,2] [ ,3] [ ,4] [1 ,] 15.0 15.1 15.2 15.2 [2 ,] 16.0 15.9 16.0 16.4 [3 ,] 15.2 NA 15.3 15.3 [4 ,] 15.7 15.6 15.8 16.0 * * * * * * * Fin Print ( trajectoires ) * * * * * * *

Comme print nexiste pas pour TrajDecoupees, cest print pour Trajectoires qui est appele. Autrement dit, la nextMethod de print pour TrajDecoupees est print e pour Trajectoires. Un petit exemple et tout sera plus clair. Nous allons dnir print e 2. pour TrajDecoupees
> setMethod( + f = " print " , + signature = " TrajDecoupees " , + d e f i n i t i o n = function (x ,...){ + callNextMethod () + cat ( "L ' objet contient galement " ) e + cat ( length ( x@listePartitions ) , " partition " ) + cat ( " \ n * * * * * Fin de print ( TrajDecoupees ) * * * * * \ n " ) + return ( invisible ()) + } + ) [1] " print " 2. Naturellement, dans un cas rel, nous ferions beaucoup plus quacher les trajectoires et le nombre e de partitions.

76

CHAPITRE 9. HERITAGE

> print ( tdCochin ) * * * Class Trajectoires , method Print * * * * Temps = [1] 1 3 4 5 * Traj = [ ,1] [ ,2] [ ,3] [ ,4] [1 ,] 15.0 15.1 15.2 15.2 [2 ,] 16.0 15.9 16.0 16.4 [3 ,] 15.2 NA 15.3 15.3 [4 ,] 15.7 15.6 15.8 16.0 * * * * * * * Fin Print ( trajectoires ) * * * * * * * L ' objet contient galement2 partition e * * * * * Fin de print ( TrajDecoupees ) * * * * *

callNextMethod peut soit prendre des arguments explicites, soit aucun argument. Dans ce cas, les arguments qui ont t passs ` la mthode actuelle sont intgralement ee e a e e passs ` la mthode suivante. e a e Quelle est la mthode suivante, voil` toute la dicult et lambigit de e a e u e callNextMethod. Dans la plupart des cas, les gens tr`s forts savent, les moins e forts ne savent pas. Mais l` o` cela devient totalement impropre, cest que la a u mthode suivante peut dpendre de la structure dune autre classe. Au nal, personne e e ne peut savoir. Exemple : dnissons une classe A qui hrite de la classe B, classe que e e quelquun dautre a programme. Quelle est la mthode suivante de initialize pour e e A ? Cela dpend. Comme A hrite, R va chercher dans lordre : e e initialize pour B initialize par dfaut. Cette mthode se termine par un validObject. e e validObject pour A validObject pour B validObject par dfaut. e A partir de l`, il nest pas possible de savoir parce que a ne dpend plus de nous ! a c e Si le programmeur de B a dni un initialize, il est appel et donc peut-tre que le e e e validObject pour B sera appel, peut-tre pas. Sinon, cest le initialize par dfaut e e e qui est appel, et donc le validObject pour A, celui de B ou celui par dfaut en fonction e e de ce qui existe. Il est donc tr`s dicile de savoir ce que le programme fait vraiment. e Plus grave, si le programmeur de B supprime ou ajoute un initialize, cela peut changer le comportement de notre mthode. Par exemple, si initialize pour e B nexiste pas et que validObject pour A existe, initialize par dfaut est appel puis e e validObject pour A. Si la mthode initialize pour B est cre, initialize par de ee e faut ne sera plus utilis mais surtout il est probable que validObject ne sera plus utilis e e non plus. Probable... Mais on ne sait pas vraiment. Incertitude fortement dsagrable, nest-ce pas ? Voil` pourquoi lutilisation de e e a callNextMethod est ` proscrire, surtout que as et is permettent de faire ` peu pr`s a a e la mme chose. e

9.8. IS, AS ET AS<-

77

9.8

is, as et as<-

Quand un objet hrite dun autre, on peut avoir besoin quil adopte momentanment e e le comportement quaurait son p`re. Pour cela, il est possible de le transformer en objet e de la classe de son p`re grce ` as. Par exemple, si on veut imprimer tdPitie en ne e a a considrant que son aspect Trajectoires : e
> print ( as ( tdPitie , " Trajectoires " )) ~ ~ ~ ~ ~ Trajectoires : initiateur ~ ~ ~ ~ ~ * * * Class Trajectoires , method Print * * * * Temps = numeric (0) * Traj = <0 x 0 matrix > * * * * * * * Fin Print ( trajectoires ) * * * * * * *

Cela va nous servir dans la dnition de show pour les TrajDecoupees : e


> setMethod( + f = " show " , + signature = " TrajDecoupees " , + d e f i n i t i o n = function ( object ){ + show ( as ( object , " Trajectoires " )) + lapply ( object@listePartitions , show ) + } + ) [1] " show "

On peut vrier quun objet est hritier dun autre grce ` is. is vrie que les e e a a e attributs de lobjet sont prsents dans la classe ls : e
> is ( trajCochin , " TrajDecoupees " ) [1] FALSE > is ( tdCochin , " Trajectoires " ) [1] TRUE

Enn, as<- permet de modier uniquement les attributs quun objet hrite de e son p`re. as(objetFils,"ClassPere")<-objetPere aecte le contenu des attributs e objetPere aux attributs dont objetFils a hrit. e e
> # ## Cr ation d ' un TrajDecoupees vide e > tdStAnne <- new( " TrajDecoupees " ) ~ ~ ~ ~ TrajDecoupees : initiateur ~ ~ ~ ~ > > > > # ## Affectation d ' un objet Trajectoires # ## aux attributs d ' un TrajDecoupees as ( tdStAnne , " Trajectoires " ) <- trajStAnne tdStAnne

78

CHAPITRE 9. HERITAGE

~ ~ ~ ~ ~ Trajectoires : initiateur ~ ~ ~ ~ ~ * * * Class Trajectoires , method Show * * * * Temps = [1] 1 2 3 4 5 6 7 8 9 * Traj ( limit ` une matrice 10 x10 ) = e a [ ,1] [ ,2] [ ,3] [ ,4] [ ,5] [ ,6] [1 ,] 16.25 16.1 16.16 16.53 16.67 17.2 [2 ,] 16.23 16.36 16.45 16.4 17.14 17 [3 ,] 15.89 16.02 16.15 16.69 16.77 16.62 [4 ,] 15.63 16.25 16.4 16.6 16.65 16.96 [5 ,] 16.16 15.85 15.97 16.32 16.73 16.94 [6 ,] 15.96 16.2 16.53 16.4 16.47 16.95 [7 ,] 16.03 16.33 16.23 16.67 16.79 17.14 [8 ,] 15.69 16.06 16.63 16.72 16.81 17.16 [9 ,] 15.82 16.17 16.75 16.76 16.78 16.51 [10 ,] 15.98 15.76 16.1 16.54 16.78 16.89 * ... ... * * * * * * * Fin Show ( trajectoires ) * * * * * * *

10 12 14 16 18 20 22 24 [ ,7] 17.55 16.84 17.52 17.02 16.73 16.73 17 16.98 17.19 17.22 [ ,8] 17.3 17.25 17.26 17.39 16.98 17.36 17.35 17.41 17.21 17.18 [ ,9] 17.47 17.98 17.46 17.5 17.64 17.33 17.58 17.51 17.84 16.94 [ ,10] 17.55 17.43 17.6 17.67 17.72 17.55 17.99 17.43 17.95 17.36

9.9

setIs

En cas dhritage, as et is sont dnis naturellement, comme nous venons de le e e voir. Il est galement possible de les prciser manuellement. Par exemple, la classe e e TrajDecoupees contient une liste de Partitions. Elle nhrite pas directement de e Partition (a serait un cas dhritage multiple impropre), donc is et as ne sont pas c e dnis par dfaut. e e Il est nanmoins possible de forcer les choses. Par exemple, on veut pouvoir conside e rer un objet de classe TrajDecoupees comme une Partition, celle ayant le plus grand nombre de groupes. Cela se fait avec linstruction setIs. setIs est une mthode qui e prend quatre arguments from est la classe de lobjet initial, celui qui doit tre transform. e e to est la classe en laquelle lobjet doit tre transform e e coerce est la fonction utilise pour transformer from en to. e
> setIs ( + class1 = " TrajDecoupees " , + class2 = " Partition " , + coerce = function ( from , to ){ + getNbGroupes <- function ( partition ){ + return ( partition [ " nbGroupes " ]) + } + nombreGroupes <+ sapply ( from@listePartitions , getNbGroupes ) + plusGrand <- which . max ( nombreGroupes ) + to <-new( " Partition " ) + to@nbGroupes <+ from@listePartitions [[ plusGrand ]][ " nbGroupes " ] + to@part <- from@listePartitions [[ plusGrand ]][ " part " ] + return ( to )

9.9. SETIS
+ } + ) > as ( tdCochin , " Partition " ) An object of class " Partition " Slot " nbGroupes " : [1] 3 Slot " part " : [1] A C C B Levels : A B C

79

Ca marche pour ce dont nous avions besoin. Mais un Warning apparait. R nous annonce que as<- nest pas dni. as<- est loprateur utilis pour aecter une valeur e e e a ` un objet alors quil est considr comme un autre objet. Dans notre cas, as<- est ee loprateur utilis pour modier TrajDecoupees alors quelle est considre comme une e e ee Trajectoires. Cela se fait grce au quatri`me argument de setIs : a e replace est la fonction utilise pour les aectations. e Dans le cas prsent, nous voudrions remplacer la partition ayant le plus grand nombre e de groupes par une nouvelle :
> setIs ( + class1 = " TrajDecoupees " , + class2 = " Partition " , + coerce = function ( from , to ){ + getNbGroupes <- function ( partition ){ + return ( partition [ " nbGroupes " ]) + } + nombreGroupes <+ sapply ( from@listePartitions , getNbGroupes ) + plusGrand <- which . max ( nombreGroupes ) + to <-new( " Partition " ) + to@nbGroupes <+ from@listePartitions [[ plusGrand ]][ " nbGroupes " ] + to@part <- from@listePartitions [[ plusGrand ]][ " part " ] + return ( to ) + }, + replace = function ( from , values ){ + getNbGroupes <- function ( partition ){ + return ( partition [ " nbGroupes " ]) + } + nombreGroupes <+ sapply ( tdCochin@listePartitions , getNbGroupes ) + plusGrand <- which . max ( nombreGroupes ) + from@listePartitions [[ plusGrand ]] <- values + return ( from ) + } + ) > as ( tdCochin , " Partition " ) <- partCochin2

Plus de Warning, la vie est belle.

80

CHAPITRE 9. HERITAGE

Eventuellement, il est possible dajouter un cinqui`me argument, la fonction test : e elle subordonne la transformation de class1 en class2 ` une condition. a Nous venons dexpliquer ` R comment considrer un objet TrajDecoua e pe comme une Partition. En ralit, un tel usage serait impropre, une e e TraDecoupees na pas ` devenir une Partition. Si nous voulons aca cder ` une partition particuli`re, il nous faut dnir un getteur (par exemple e a e e getPartitionMax). De mani`re plus gnrale, setIs est une fonction ` viter. R converti naturellee e e a e ment ce qui doit tre converti. setIs ajoute des conversions articielles au gr du proe e grammeur, conversions qui seront peut-tre surprenantes pour lutilisateur. Et comme e toujours, les surprises sont ` proscrire... a

9.10

Les classes virtuelles

Il peut arriver que des classes soient proches sans que lune soit une extension de lautre. Par exemple, nous allons concevoir deux types de partitionnement : des dcoue pages qui tiquettent les individus sans les juger et ceux qui valuent les individus. e e Le premier type de dcoupage sera non ordonn (la mme chose que Partition) et e e e le deuxi`me type de dcoupe sera ordonn (par exemple, il classera les individus en e e e Insuffisant, Moyen, Bien). Les attributs de cette deuxi`me classe seront nbGroupes, e un entier qui indique le nombre de modalits de lvaluation et part, une variable ore e donne qui indiquera le groupe dappartenance. Clairement, les attributs ne sont pas les e mmes dans les deux classes puisque part est ordonn dans lune et pas dans lautre. e e Donc lune ne peut pas hriter de lautre. Pourtant, les mthodes seront semblables dans e e bon nombre de cas. Pour ne pas avoir ` les programmer en double, on peut faire appel ` une classe a a virtuelle. Une classe virtuelle est une classe pour laquelle il nest pas possible de crer e des objets mais qui peut avoir des hritiers. Les hritiers bncient ensuite des mthodes e e e e e cres pour la classe. Dans notre cas, nous allons crer une classe virtuelle PartitionPere ee e puis deux classes ls PartitionSimple et PartitionEvaluante. Toutes les mthodes e communes seront cres pour PartitionPere, les deux ls en hriteront. ee e
> setClass ( + Class = " PartitionPere " , + representation = representation ( nbGroupes = " numeric " ," VIRTUAL " ) + ) [1] " PartitionPere " > setClass ( + Class = " PartitionSimple " , + representation = representation ( part = " factor " ) , + contains = " PartitionPere " + )

9.10. LES CLASSES VIRTUELLES

81

[1] " PartitionSimple " > setClass ( + Class = " PartitionEvaluante " , + representation = representation ( part = " ordered " ) , + contains = " PartitionPere " + ) [1] " PartitionEvaluante " > setGeneric ( " nbMultDeux " , + function ( object ){ standardGeneric ( " nbMultDeux " )} + ) [1] " nbMultDeux " > setMethod( " nbMultDeux " ," PartitionPere " , + function ( object ){ + object@nbGroupes <- object@nbGroupes * 2 + return ( object ) + } + ) [1] " nbMultDeux " > a <- new( " PartitionSimple " , nbGroupes =3 , + part = f a c t o r ( LETTERS [ c (1 ,2 ,3 ,2 ,2 ,1)]) + ) > nbMultDeux ( a ) An object of class " PartitionSimple " Slot " part " : [1] A B C B B A Levels : A B C Slot " nbGroupes " : [1] 6 > b <- new( " PartitionEvaluante " , nbGroupes =5 , + part = ordered ( LETTERS [ c (1 ,5 ,3 ,4 ,2 ,4)]) + ) > nbMultDeux ( b ) An object of class " PartitionEvaluante " Slot " part " : [1] A E C D B D Levels : A < B < C < D < E Slot " nbGroupes " : [1] 10

Et voil`... a

82

CHAPITRE 9. HERITAGE

9.11

Pour les dyslexiques...

Pour conclure avec lhritage, une petite astuce mnmotechnique destine aux dyse e e lexiques (dont moi) qui se mlangent assez vite les neurones et qui ne savent jamais si e lhritier peut utiliser les techniques du p`re ou si cest linverse : lhistoire est issue de e e Contes et lgendes de la naissance de Rome [3]. Lauteur explique que, contrairement e aux humains les Dieux naiment pas avoir des enfants plus puissants queux. Cest pour a que Saturne dvore ses propres enfants ` leur naissance (pour les motifs, rassurezc e a e vous, a nest tout de mme pas trop grave pour les enfants puisque lorsque Saturne se c e fait nalement couper en deux par son ls Jupiter, tous sortent de son ventre et sont bien vivants !). Chez les humains, cest linverse, les p`res sont plutt ers davoir des e o enfants plus grands, qui les battent au tennis (sur le moment ils rlent, mais apr`s ils a e racontent ` leurs copains), avec un meilleur niveau dtude... Cest lascenseur social qui a e fonctionne. Chez les objets, cest pareil que chez les humains : Les ls sont plus forts que les p`res. Un ls peut faire tout ce que fait le p`re, plus ce qui lui est propre 3 e e

3. Pour les mta-dyslexiques qui se souviendront de cette histoire mais qui ne sauront plus si les e objets se comportent comme des Dieux ou des humains, on ne peut plus rien faire... 4 4. Les objets sont trus de bugs, ajoute un relecteur, comme les humains, (Alors que chacun sait e que les Dieux sont parfaits !) Voil` pour les mta-dyslexiques. a e

Chapitre 10

Modication interne dun objet


La suite ncessite de descendre un peu plus profondment dans les mandres du e e e fonctionnement de R...

10.1

Fonctionnement interne de R : les environnements

Un environnement est un espace de travail permettant de stocker des variables. Pour simplier, R travaille en utilisant deux environnements : le global et le local. Le global est celui auquel nous avons acc`s quand nous tapons des instructions dans la console. e Le local est un environnement qui se cre ` chaque appel de fonction. Puis, quand la e a fonction se termine, le local est dtruit. Exemple : e
> + + + + > > > 2 > # ## Appel de la fonction et cr ation de x ' local ' e > func () 5 > # ## Retour au global , suppression de x local > cat ( x ) 2 func <- function (){ x <- 5 cat ( x ) return ( invisible ()) } # ## Creation de x ' global ' x <- 2 cat ( x )

La fonction func est dnie dans lenvironnement global. Toujours dans le global, x e reoit la valeur 2. Puis la fonction func est appele. R cre donc lenvironnement local. c e e 83

84

CHAPITRE 10. MODIFICATION INTERNE DUN OBJET

Dans le local, il donne ` x la valeur 5. Mais uniquement dans le local. A ce stade, il a existe donc deux x : un global qui vaut 2 et un local qui vaut 5. La fonction ache le x local puis se termine. Lenvironnement local est alors dtruit. e Ainsi, le x qui valait 5 disparait. Reste le x qui vaut 2, le global.

10.2

Mthode pour modier un attribut e

Retour ` nos trajectoires. Il nous reste une troisi`me mthode ` dnir, celle qui a e e a e impute les variables. Pour simplier, nous imputerons en remplaant par la moyenne 1 . c
> meanSansNa <- function ( x ){ mean (x , na . rm =TRUE)} > setGeneric ( " impute " , function ( object ){ standardGeneric ( " impute " )}) [1] " impute " > setMethod( + f = " impute " , + signature = " Trajectoires " , + def = function ( object ){ + moyenne <- apply ( object@traj ,2 , meanSansNa ) + f o r ( iCol in 1: ncol ( object@traj )){ + object@traj [ is . na ( object@traj [ , iCol ]) , iCol ] <+ moyenne [ iCol ] + } + return ( object ) + } + ) [1] " impute " > impute ( trajCochin ) * * * Class Trajectoires , method Show * * * * Temps = [1] 2 3 4 5 * Traj ( limit ` une matrice 10 x10 ) = e a [ ,1] [ ,2] [ ,3] [ ,4] [1 ,] 15 15.1 15.2 15.2 [2 ,] 16 15.9 16 16.4 [3 ,] 15.2 15.53 15.3 15.3 [4 ,] 15.7 15.6 15.8 16 * ... ... * * * * * * * Fin Show ( trajectoires ) * * * * * * *

La mthode impute fonctionne correctement. Par contre, elle ne modie pas e trajCochin.
> trajCochin 1. Pour des trajectoires, cette mthode nest pas bonne, il vaudrait mieux imputer par la moyenne e des valeurs encadrant la manquante. Mais le but de ce manuel est dapprendre S4, pas de devenir des experts es-trajectoire. Nous allons donc au plus simple.

10.2. METHODE POUR MODIFIER UN ATTRIBUT

85

* * * Class Trajectoires , method Show * * * * Temps = [1] 2 3 4 5 * Traj ( limit ` une matrice 10 x10 ) = e a [ ,1] [ ,2] [ ,3] [ ,4] [1 ,] 15 15.1 15.2 15.2 [2 ,] 16 15.9 16 16.4 [3 ,] 15.2 NA 15.3 15.3 [4 ,] 15.7 15.6 15.8 16 * ... ... * * * * * * * Fin Show ( trajectoires ) * * * * * * *

A la lumi`re de ce que nous venons de voir sur les environnements, que fait cette e mthode ? Elle cre localement un objet object, elle modie ses trajectoires (imputation e e par la moyenne) puis elle retourne un objet. Le fait davoir tap impute(trajCochin) e na donc eu aucun eet sur trajCochin. Conceptuellement, cest un probl`me. Bien sr, il est facile de le contourner, simplee u ment en utilisant
> trajCochin <- impute ( trajCochin )

Mais impute est une fonction qui a pour vocation de modier lintrieur de lobjet, e pas de crer un nouvel objet et de le raecter. Pour lui rendre son sens premier, nous e e pouvons utiliser assign. assign est un des oprateurs les plus impropres qui soit... Il permet, alors e quon se trouve dans lenvironnement local, de modier des variables au niveau global. Cest tr`s mal. Mais dans le cas prsent, cest justement ce que R e e ne nous ore pas, et qui est pourtant classique en programmation objet. Donc, nous nous permettons ici une petite entorse aux r`gles (ne le dites ` personne, hein ?) en esprant e a e quune prochaine version de R int`gre la modication interne... e Nous allons donc r-crire impute en ajoutant deux petites instructions : ee deparse(substitute()) permet de connaitre le nom de la variable qui, au niveau global, a t passe comme argument ` la fonction en cours dexcution. ee e a e assign permet de modier une variable de niveau suprieur. Plus prcisment, il e e e nexiste pas un niveau local, mais des niveaux locaux. Par exemple, une fonction dans une autre fonction cre un local dans le local, une sorte de sous-local ou de local niveau 2. e Lutilisation de assign que nous proposons ici naecte donc pas le niveau global, mais le niveau local suprieur. Modier directement le global serait encore plus impropre... e
> + + + + + > > essaiCarre <- function ( x ){ nomObject <- deparse ( substitute ( x )) print ( nomObject ) assign ( nomObject , x ^2 , envir = parent . frame ()) return ( invisible ()) } a <-2 essaiCarre ( a )

[1] " a "

86

CHAPITRE 10. MODIFICATION INTERNE DUN OBJET

> a [1] 4

Voil` donc impute nouvelle version. Pour lutiliser, plus besoin de faire une aection. a Pour les Trajectoires, cela donne :
> setMethod( + f = " impute " , + signature = " Trajectoires " , + def = function ( object ){ + nameObject <- deparse ( substitute ( object )) + moyenne <- apply ( object@traj ,2 , meanSansNa ) + f o r ( iCol in 1: ncol ( object@traj )){ + object@traj [ is . na ( object@traj [ , iCol ]) , iCol ] <+ moyenne [ iCol ] + } + assign ( nameObject , object , envir = parent . frame ()) + return ( invisible ()) + } + ) [1] " impute " > impute ( trajCochin ) > trajCochin * * * Class Trajectoires , method Show * * * * Temps = [1] 2 3 4 5 * Traj ( limit ` une matrice 10 x10 ) = e a [ ,1] [ ,2] [ ,3] [ ,4] [1 ,] 15 15.1 15.2 15.2 [2 ,] 16 15.9 16 16.4 [3 ,] 15.2 15.53 15.3 15.3 [4 ,] 15.7 15.6 15.8 16 * ... ... * * * * * * * Fin Show ( trajectoires ) * * * * * * *

Ca marche. Encore une fois, assign est un oprateur impropre ` manipu e a ler avec beaucoup de prcautions, il peut provoquer des catastrophes pare faitement contre-intuitives. Mais pour la modication interne, il est ` ma a connaissance la seule solution.

Quatri`me partie e

Annexes

87

Annexe A

Remerciements
A.1 Nous vivons une poque formidable e

Quand on vit un moment historique, une rvolution, une date clef, on ne sen rend pas e toujours compte. Je pense que la cration dInternet sera considre par les historiens e ee futurs comme une avance majeure, quelque chose daussi norme que linvention de e e lcriture ou limprimerie. Lcriture, cest la conservation de linformation. Limprimerie, e e cest la diusion de linformation ` une lite, puis ` tout le monde, mais avec un cot. a e a u Internet, cest linstantanit, la gratuit, le partage global, les connaissances des experts e e e mises ` la disposition de tous... Les forums, cest la n des questions sans rponses... a e Il y a quelque temps, je ne connaissais de la S4 que le nom. En quelques mois, jai pu acqurir des connaissances srieuses grce ` des gens que je ne connais pas, mais qui e e a a mont aid. Bien sr, jai beaucoup lu. Mais d`s que javais une question, je la posais le e u e soir, je dormais du sommeil du juste et le lendemain matin, javais ma rponse. Cest e gratuit, cest de laltruisme, cest tout simplement merveilleux. Nous vivons une poque e formidable...

A.2

Ceux par qui ce tutorial existe...

Un grand merci donc ` de nombreuses personnes dont certaines que je ne connais pas. a Pierre Bady, inestimable relecteur, ma fait des remarques tr`s pertinentes, en particulier e sur la structure gnrale du document qui partait un peu dans tous les sens... Martin e e Morgan, non seulement connait TOUT sur la S4, mais de surcroit dgaine plus vite que e son ombre quand il faut rpondre ` une question sur r-help... Merci aussi ` lquipe e a a e du CIRAD qui anime le forum du Groupe des Utilisateurs de R. Jamais on ne se fait jeter, jamais le moindre RTFM ou GIYF 1 . Cest cool. Bruno Falissard ma donn (par e ordre dcroissant dimportance) une quipe 2 , son amour de R, un th`me de recherche, e e e des ides, des contacts, un bureau, un ordi mga puissant... Sans lui, je serais sans e e
1. Read The Fucking Manuel ou Google Is Your Friend, rponses classiques faites a ceux qui posent e ` des questions sans avoir pris le temps de chercher par eux-mmes. e 2. La MEILLEEEEUUUURE des quipes ! e

89

90

ANNEXE A. REMERCIEMENTS

doute encore en train de vgter dans une impasse. Merci ` Scarabette pour ses avis, sa e e a fraicheur et son impertinence. Merci ` Cathy et Mich`le, mes deux chasseuses de fautes a e prfres. Enn, merci ` la R Core Team pour the free gift of R... eee a

Annexe B

Mmo e
Ca y est, vous avez tout lu, tout compris, vous tes en train de programmer vos e propres objets ? Juste un petit trou de mmoire : cest quoi dj` le nom du troisi`me e ea e attribut de validObject ?

B.1

Cration e

# ## Cr ation de la classe e . NewClass . valid <- function ( object ){ return (TRUE)} setClass ( Class = " NewClass " , representation = representation ( x = " numeric " ,y = " character " ) , prototype = prototype ( x =1 , y = " A " ) , contains = c ( " FatherClass " ) , v a l i d i t y =. NewClass . valid ) rm (. NewClass . v a l i d i t y ) # ## Cr ation d ' un objet e new( Class = " NewClass " ) A <- new( Class = " NewClass " ,x =2 , y = " B " ) A@x <- 4 # ( beurk ! ) # ## Destruction d ' une classe removeClass( " NewClass " ) # ## Constructeur newClass <- function (){ return (new( Class = " NewClass " ))}

B.2

Validation

. NewClass . initialize <- function ( object , value ){ i f (....){ STOP ( " initialize ( NewClass ) : Erreur " )} e l s e {} object@x <- value ; object@y <- value ^2;

91

92
validObject ( object ) return ( object ) } setMethod( f = " initialize " , signature = " NewClass " , d e f i n i t i o n =. NewClass . initialize ) rm (. NewClass . initialize )

ANNEXE B. MEMO

B.3
> > + + > > + +

Accesseur

# ## Getteur setMethod( f = " [ " , signature = " NewClass " , d e f i n i t i o n = function ( object ){ return ( object@x )} ) # ## Setteur setReplaceMethod( f = " [ " , signature = " NewClass " , def = function ( object , value ){ object@x <- value ; return ( object )} )

B.4
> > + + > > + + > >

Mthodes e

# ## Rendre une m thode g n rique e e e setGeneric ( f = " newFunction " , def = function (z , r ){ standardGeneric ( " newFunction " )} ) # ## D clarer une m thode e e setMethod( f = " newFunction " , signature = " NewClass " , def = function (z , r ){.... ; return (....)} ) # ## Pour connaitre les arguments d ' une fonction args ( NewFunction )

B.5

Quelques fonctions incontournables


args(print) : (x,...) args(show) : (object) args(plot) : (x,y,...) args(summary) : (object,...) args(length) : (x)

B.6

Voir la structure des objets

slotNames("Trajectoires") : donne le nom des attributs de lobjet (mais pas leur type). getSlots("Trajectoires") : donne les attributs de lobjet et leur type.

B.6. VOIR LA STRUCTURE DES OBJETS

93

getClass("Trajectoires") : donne les attributs de lobjet, leur type, les hritiers e et les anctres. e getClass("Trajectoires",complete=FALSE) : donne les attributs de lobjet, les ls et le p`re uniquement. e getMethod(f="plot",signature="Trajectoires") : donne la dnition de plot e pour lobjet Trajectoires (sans hritage). e getMethods("plot") : donne la dnition de plot pour toutes les signatures pose sibles. existsMethod(f="length",signature="Trajectoires") : retourne vrai si la mthode existe (sans dhritage) pour la classe en question. e e selectMethod(f="length",signature="Trajectoires") : donne la dnition de e length pour lobjet Trajectoires (avec hritage). e hasMethod("length","Trajectoires") : retourne vrai si la mthode existe pour e Trajectoires (avec hritage). e showMethods("plot") : ache toutes les signatures utilisables pour la mthode e plot. showMethods(classes="Trajectoires") : ache toutes les mthodes dnies e e pour la classe Trajectoires findMethod("plot","Trajectoires") : donne lenvironnement dans lequel plot pour Trajectoires est dni. e

94

ANNEXE B. MEMO

Annexe C

Pour aller plus loin


La littrature sur la S4 est assez sommaire, et pratiquement exclusivement en anglais. e Voil` un petit aperu de ce quon peut trouver : a c S4 Classes in 15 pages more or less [1] : Un bon tutorial pour commencer. S4 Classes and Methods [2] : comme prcdemment, un tutorial simple pour come e mencer. S Programming[5] : le chapitre sur la S4 est court, mais il est assez clair. A (Not so) Short Introduction to S4 : premi`re version du livre que vous avez entre e les mains. Le Green Book prsente galement un chapitre sur la S4, mais il est un peu obscur... e e Enn, signalons lexistence dun wiki ddi ` la programmation S4 [6] e ea

95

96

ANNEXE C. POUR ALLER PLUS LOIN

Liste des tables et gures


Diagramme des classes, exemple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 Trajectoires . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .21 Diagramme des classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 Arbre dhritage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 e Arborescence de packClassic, ` la main . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ?? a Arborescence de packClassic, selon pacakge.squeleton . . . . . . . . . . . . . . . . . . . . . . . . . . ?? Correspondance visible/invisible/publique/prive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ?? e Arborescence de packClassic, version nale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ?? Arborescence de packS4, ` la main . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .?? a Arborescence de packS4, selon pacakge.squeleton . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ?? Liste des chiers daides et alias selon pacakge.squeleton . . . . . . . . . . . . . . . . . . . . . . . . .?? Classe et mthodes dans un unique cher . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ?? e Classe et mthodes dans des chers spars . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ?? e e e Liste des chiers daides et alias, apr`s modications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ?? e Arborescence de packS4, version nale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ??

Bibliographie
[1] R. Gentleman. S4 Classes in 15 Pages More or Less, 2002 http://www.bioconductor.org/develPage/guidelines/programming/S4Objects.pdf. [2] F. Leisch. S4 Classes and Methods, 2004 http://www.ci.tuwien.ac.at/Conferences/useR-2004/Keynotes/Leisch.pdf. [3] L. Orvieto. Contes et Lgendes de la naissance de Rome. Nathan, 1968. e [4] E. Paradis. R pour les debutants, 2002 http://cran. r-project. org/doc/contrib/rdebuts fr. pdf. [5] W.N. Venables and B.D. Ripley. S Programming. Springer, 2000. [6] Wiki. tips:classes-S4, http://wiki.r-project.org/rwiki/doku.php?id=tips:classes-s4.

97

Index
- Symbols <- . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 @ . . . . . . . . . . . . . . . . . . . . . . . . . . . 31, 45, 53, 58 [ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56, 58, 92 [<- . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56, 92 -Aaccesseur . . . . . . . . . . . . . . . . . . . . . . . . . . . 53, 92 aectant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 achage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 ANY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68, 70 arbre dhritage . . . . . . . . . . . . . . . . . . . . . . . . 72 e args . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 as . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 as<- . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77, 79 assign . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 attr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 attribut . . . . . . . . . . . . . . . . . . . . . . . . 19, 29, 31 attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 avance majeure . . . . . . . . . . . . . . . . . . . . . . . 89 e -Bboite ` moustache. . . . . . . . . . . . . . . . . . . . . .35 a -Cct obscur16, 17, 23, 25, 2933, 37, 40, 44, oe 45, 48, 49, 57, 58, 72, 76, 80, 85, 86 callNextMethod . . . . . . . . . . . . . . . . . . . 75, 76 character . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 character . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 CIRAD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 classe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19, 29 virtuelle . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 cluster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 coerce . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 constructeur . . . . . . . . . . . . . . . . 19, 30, 48, 50 construction . . . . . . . . . . . . . . . . . . . . . . . . 43, 45 contains . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 contrle de type. . . . . . . . . . . . . . . . . . . . . . . .29 o -Ddef . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 deparse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 donnes manquantes . . . . . . . . . . . . . . . . . . . 22 e drop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 dyslexique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 -Eencapsulation . . . . . . . . . . . . . . . . . . . . . . . . . . 15 environnement . . . . . . . . . . . . . . . . . . . . . . . . . 85 global. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .83 local . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 environnement . . . . . . . . . . . . . . . . . . . . . . . . 83 poque formidable . . . . . . . . . . . . . . . . . . . . . 89 e erreur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12, 32 initialisation . . . . . . . . . . . . . . . . . . . . . . . 32 typage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 typographique. . . . . . . . . . . . . . . . . .57, 58 valeur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 exemple. . . . . . . . . . . . . . . . . . . . . . . . .2124, 64 existsMethod . . . . . . . . . . . . . . . . . . 42, 73, 92 -Ff . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 factor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23, 33 chier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 ls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14, 69, 80

98

INDEX

99

spcique . . . . . . . . . . . . . . . . . . . . . . . . . . 39 e findMethod . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 validation . . . . . . . . . . . . . . . . . . 20, 25, 43 fonction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11, 19 from . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 matplot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 -GminiKml . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3, 66 gnrique. . . . . . . . . . . . . . . . . . . . . . . . . . .39, 41 missing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 e e get . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53, 58, 92 -NgetClass . . . . . . . . . . . . . . . . . . . . . . . . . . 34, 92 name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 getMethod. . . . . . . . . . . . . . . . . . . . . .42, 73, 92 getMethods . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 nbCluster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 getSlots . . . . . . . . . . . . . . . . . . . . . . . . . . 34, 92 nbGroupes . . . . . . . . . . . . . . . . . . . . . . . . . 23, 80 getteur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53, 92 new . . . . . . . . . . . . . . . . . . . . . . . . . 30, 38, 73, 91 grand-p`re . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 nextMethod . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 e graphe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 nuage de points . . . . . . . . . . . . . . . . . . . . . . . . 35 NULL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 -Hnumeric . . . . . . . . . . . . . . . . . . . . . . . . 23, 33, 64 hritage . . . . . . . . . . 14, 23, 69, 72, 77, 78, 80 e -Omultiple . . . . . . . . . . . . . . . . . . . . . . . . 72, 78 objet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11, 19 hasMethod . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 dnition . . . . . . . . . . . . . . . . . . . . . . . . . . 19 e hasMethods . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 vide . . . . . . . . . . . . . . . . . . . . . . . . 33, 38, 47 -I-Pi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 p`re . . . . . . . . . . . . . . . . . . . . . . . . 14, 69, 70, 80 e IMC . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12, 21, 47 imputation . . . . . . . . . . . . . . . . . . . . . . . . . 23, 84 part. . . . . . . . . . . . . . . . . . . . . . . . . . . .23, 64, 80 impute . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8486 Partition. . . . . . . . . . . . . . . . . . . . . .23, 63, 80 Indice de Masse Corporelle . . . . . . . . . . . . . 12 partition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 initialisation . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 PartitionEvaluante . . . . . . . . . . . . . . . . . . 80 initialize . . . . . . . . . . . . . . . . . . . . 45, 73, 76 PartitionPere . . . . . . . . . . . . . . . . . . . . . . . . 80 initiateur . . . . . . . . . . . . . . . . . . . . . . . . . . . 45, 50 PartitionSimple . . . . . . . . . . . . . . . . . . . . . . 80 instruction surprenante . . . . . . . . . . . . . . . . 17 pause . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 integer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 plot . . . . . . . . . . . . . . . . . . . . 25, 35, 39, 64, 66 is . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 print . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25, 37 programmation objet . . . . . . . . . . . . . . . . . . 11 -Linconvnients . . . . . . . . . . . . . . . . . . . . . . 15 e length . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 prsentation . . . . . . . . . . . . . . . . . . . . . . . 13 e listePartitions . . . . . . . . . . . . . . . . . . 24, 71 prototype . . . . . . . . . . . . . . . . . . . . . . . . . 32, 44 lockBinding . . . . . . . . . . . . . . . . . . . . . . . . . . 40 -R-MR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 mthode . . . . . . . . . . . . . . . . . . . . 19, 35, 64, 92 R Core Team . . . . . . . . . . . . . . . . . . . . . . . . . . 90 e autre . . . . . . . . . . . . . . . . . . . . . . . . . . . 20, 25 r`gle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 e cration . . . . . . . . . . . . . . . . . . . . 19, 25, 43 racine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 e gnrique . . . . . . . . . . . . . . . . . . . . . . 39, 41 remerciement . . . . . . . . . . . . . . . . . . . . . . . . . . 89 e e manipulation dattribut . . . . . . . . 20, 25 removeClass . . . . . . . . . . . . . . . . . . . . . . . 32, 91

100

INDEX

e replace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 valeur par dfaut. . . . . . . . . . . . . . . . . . . . . . .32 representation . . . . . . . . . . . . . . . . . . . 29, 44 validity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 validObject . . . . . . . . . . . . . . . . . . . . . . . 46, 76 -Svariable . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11, 19 S-plus. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .11 nature . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 S3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 nominale . . . . . . . . . . . . . . . . . . . . . . . . . . 23 S4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 numrique . . . . . . . . . . . . . . . . . . . . . . . . . 23 e selecteur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 e selectMethod . . . . . . . . . . . . . . . . . . . . . . 73, 92 Vehicule . . . . . . . . . . . . . . . . . . . . . . . . . . 69, 70 set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53, 92 Voiture . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69, 70 setClass . . . . . . . . . . . . . . . . . . . . . . . . . . 29, 91 setGeneric . . . . . . . . . . . . . . . . . . . . 39, 40, 92 -WsetIs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78, 80 Warning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 setMethod . . . . . . . . . . . . . . . . . . 35, 64, 91, 92 -XsetReplaceMethod. . . . . . . . . . . . . . . . . . . . .55 setteur . . . . . . . . . . . . . . . . . . . . . . 53, 55, 57, 92 x . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 setValidity . . . . . . . . . . . . . . . . . . . . . . . . . . 44 show . . . . . . . . . . . . . . . . . . . . . . . . 25, 37, 71, 77 showMethods . . . . . . . . . . . . . . . . . . . 41, 68, 92 signature . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 signature . . . . . . . . . . . . . . . . . . . . . . . . . 36, 64 slotNames . . . . . . . . . . . . . . . . . . . . . . . . . 34, 92 spcique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 e Sportive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 substitute . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 -Ttemps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22, 24 test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 to . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 traj . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22, 24 TrajDecoupees . . . . . . . . . 23, 69, 70, 72, 79 trajectoire . . . . . . . . . . . . . . . . . . . . . . . . . . 21, 35 Trajectoires . . . 22, 43, 64, 70, 77, 79, 86 trajectoires . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 trajectoires . . . . . . . . . . . . . . . . . . . . . . . . . 48 type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .29, 40 fonction . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 -Uunclass . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 -Vvricateur . . . . . . . . . . . . . . . . . . . . . . . . . 43, 51 e valeur manquante . . . . . . . . . . . . . . . . . . . . . . 22