Listing du fichier tutrprog.php
00001 <?php
00002 # # (gH) -_- index.php ; TimeStamp (unix) : 02 Janvier 2015 vers 18:12
00003 error_reporting(E_ALL | E_NOTICE ) ;
00004 include("../../std7.php") ;
00005 include("progi.php") ;
00006 $titre = "Introduction à la programmation avec R" ;
00007 debutPage($titre,"strict") ;
00008 debutSection() ;
00009 h1($titre) ;
00010 h2(s_nbsp(16).s_span('gilles.hunault "at" univ-angers.fr',"gvert")) ;
00011
00012 #######################################################################################################################
00013
00014 pvide() ;
00015 $nbp = 9 ;
00016 h1("Ce tuteur se compose de $nbp parties :") ;
00017 pvide() ;
00018
00019 blockquote() ;
00020 for ($ipartie=1;$ipartie<=$nbp;$ipartie++) {
00021 h3("Partie $ipartie : ".ghBleu(seances($ipartie))) ;
00022 } ; # fin pour ipartie
00023 finblockquote() ;
00024 pvide() ;
00025
00026 #######################################################################################################################
00027
00028 $numcours = 1 ; partie($numcours) ; pvide() ;
00029 $rubrique = 0 ;
00030 $rubriques1 = array() ;
00031 $rubrique++ ; $rubriques1[$rubrique] = "Qu'est-ce que la programmation en R ?" ;
00032 $rubrique++ ; $rubriques1[$rubrique] = "Comment apprendre à programmer ?" ;
00033 $rubrique++ ; $rubriques1[$rubrique] = "Présentation des cours" ;
00034 $rubrique++ ; $rubriques1[$rubrique] = "Principes de programmation" ;
00035 $rubrique++ ; $rubriques1[$rubrique] = "Spécificités du langage $R" ;
00036
00037 $tdmCRLM1 = new tdm($rubriques1) ;
00038 $tdmCRLM1->titre() ;
00039 $tdmCRLM1->menu("oui","oui","nou","p$numcours") ;
00040
00041 $numRub = 0 ;
00042
00043 #######################################################################################################################
00044 #
00045 # progic1
00046 #
00047 #######################################################################################################################
00048
00049 $tdmCRLM1->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Qu'est-ce que la programmation en R ?
00050
00051 ## -------------------------------------------------------------------------------------------
00052
00053 blockquote() ;
00054
00055 p("texte") ;
00056 echo "Programmer, c'est, ".bleu("historiquement")." «".b(vert("écrire"))."» des programmes, " ;
00057 echo " c'est-à-dire des textes dans un langage spécial compris par un ordinateur. " ;
00058 echo " Ecrire est mis ici pour ".b("réaliser").", ce qui signifie à la fois concevoir, écrire, tester, documenter. " ;
00059 echo " Lorsqu'un programme est d'importance (penser à un programme qui gère le décollage des avions dans un aéroport), " ;
00060 echo " plusieurs personnes voire plusieurs centaines de personnes peuvent y participer. " ;
00061 finp() ;
00062
00063 p("texte") ;
00064 echo "L'expression ".em("langage spécial")." indique qu'il va falloir en quelque sorte apprendre une nouvelle langue, " ;
00065 echo " simplifiée (basée plus ou moins sur l'anglais) et surtout, qu'il va falloir ".em(vert("tout dire en utilisant cette langue")).". " ;
00066 echo " On utilise parfois un autre langage moins spécifique nommé ".rouge("algorithmique")." en français pour juste " ;
00067 echo " réfléchir aux idées, aux concepts et aux actions à exécuter." ;
00068 finp() ;
00069
00070 p("texte") ;
00071 echo "Dans un langage de programmation, on trouve en général cinq actions principales " ;
00072 finp() ;
00073
00074 ul() ;
00075
00076 debutli() ; p() ;
00077 echo bleu("effectuer")." un calcul (plus ou moins complexe)" ;
00078 finp() ; finli() ;
00079
00080 debutli() ; p() ;
00081 echo bleu("lire")." une ou plusieurs valeurs (au clavier, dans un fichier, en mémoire...)" ;
00082 finp() ; finli() ;
00083
00084 debutli() ; p() ;
00085 echo bleu("écrire")." une ou plusieurs valeurs (à l'écran, dans un fichier, en mémoire...)" ;
00086 finp() ; finli() ;
00087
00088 debutli() ; p() ;
00089 echo bleu("appeler")." un sous-programme (avec éventuellement des paramètres)" ;
00090 finp() ; finli() ;
00091
00092 debutli() ; p() ;
00093 echo bleu("gérer")." le flux des instructions (faire des tests ou des boucles)" ;
00094 finp() ; finli() ;
00095
00096 finul() ;
00097
00098
00099 p("texte") ;
00100 echo "La programmation en R est un peu ".b("spéciale")." dans la mesure où on n'écrit pas vraiment des " ;
00101 echo " programmes mais plutôt des ".rouge("scripts")." dans un environnement. " ;
00102 echo " Nous reviendrons régulièrement sur cette différence au travers d'exemples " ;
00103 echo " afin que vous puissiez aussi programmer dans d'autres langages. " ;
00104 finp() ;
00105
00106 finblockquote() ;
00107
00108 #######################################################################################################################
00109
00110 $tdmCRLM1->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Comment apprendre à programmer ?
00111
00112 ## -------------------------------------------------------------------------------------------
00113
00114 blockquote() ;
00115
00116 p("texte") ;
00117 echo "Pour apprendre à programmer, il faut donc utiliser les mêmes techniques que pour " ;
00118 echo " apprendre une nouvelle langue. Cela inclut donc beaucoup de pratique, de répétition, d'entrainement." ;
00119 echo " Après avoir maitrisé le ".b("vocabulaire de base").", on passe à la ".b("syntaxe")." élémentaire puis " ;
00120 echo " au bout d'un certain temps on passe à des phrases plus longues, on apprend la ".b("grammaire")." et surtout, " ;
00121 echo " on continue encore et encore..." ;
00122 finp() ;
00123
00124 p("texte") ;
00125 echo "L'avantage avec l'ordinateur, c'est qu'il est ".bleu("infiniment patient")." et qu'on ne risque pas de l'énerver en commettant toujours " ;
00126 echo " la même erreur, qu'on peut essayer et essayer encore et encore, jusqu'à temps qu'on arrive à se faire " ;
00127 echo " comprendre. Par contre, le gros défaut, c'est qu'il est ".b("bête")." ou plus exactement " ;
00128 echo b("mécanique")." et qu'il est incapable d'accepter l'".rouge("à peu près").". " ;
00129 finp() ;
00130
00131 p("texte") ;
00132 echo "Par exemple si un étranger vous dit " ;
00133 echo "«".em(vert("je voudrais un papier blanche"))."»" ;
00134 echo " ou " ;
00135 echo "«".em(vert("je voudrais une blanche papier"))."»" ;
00136 echo " vous corrigerez de vous-mêmes en ".b("papier blanc")." et vous comprendrez ce que veut la personne." ;
00137 echo " Si par contre vous demandez à l'ordinateur d'appeler le sous-programme " ;
00138 echo em(vert("CALCUL(x,)y")) ;
00139 echo " au lieu du sous-programme " ;
00140 echo em(vert("CALCUL(x,y)")) ;
00141 echo ", il ne saura que vous répondre " ;
00142 echo bleu("\"erreur de syntaxe, \"") ;
00143 echo " et peut-être, dans le meilleur des cas, " ;
00144 echo bleu("\"variable manquante après la virgule\"").". " ;
00145 finp() ;
00146
00147 finblockquote() ;
00148
00149 #######################################################################################################################
00150
00151 $tdmCRLM1->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Présentation des cours
00152
00153 ## -------------------------------------------------------------------------------------------
00154
00155 blockquote() ;
00156
00157 p("texte") ;
00158 echo "Nous allons donc progressivement apprendre des mots et les utiliser dans des phrases courtes, " ;
00159 echo " puis réfléchir pour savoir comment construire des phrases longues, " ;
00160 echo " produire automatiquement des séries de phrases, automatiser des comportements..." ;
00161 finp() ;
00162
00163 p("texte") ;
00164 echo "Une des difficultés sera de comprendre comment l'ordinateur comprend nos phrases, de mettre en " ;
00165 echo " place des automatismes, des habitudes de programmation." ;
00166 finp() ;
00167
00168 p("texte") ;
00169 echo "Le cours 1 (ce cours) insiste sur les principes généraux et doit convaincre des qualités qu'il faut " ;
00170 echo " développer pour savoir programmer. " ;
00171 echo " Le cours 2 sera focalisé sur la notion de variable et d'affectation (calcul ou remplacement de variable). " ;
00172 echo " Le cours 3 sert à apprendre comment indiquer à l'ordinateur quelles instructions réaliser en fonction de " ;
00173 echo " conditions sur les valeurs des variables (ce qu'on nomme tests logiques). " ;
00174 echo " Les boucles et itérations seront présentées au cours 4 alors que les sous-programmes seront traités dans le cours 5." ;
00175 echo " Les autres cours serviront à indiquer tout le travail qu'il reste à faire pour savoir \"bien\" programmer en R." ;
00176 finp() ;
00177
00178 finblockquote() ;
00179
00180 #######################################################################################################################
00181
00182 $tdmCRLM1->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Qu'est-ce que la programmation ?
00183
00184 ## -------------------------------------------------------------------------------------------
00185
00186 blockquote() ;
00187
00188 $sous = 0 ; # numéro de sous-rubrique
00189
00190 p("texte") ;
00191 echo "Avant de rentrer dans le détail des instructions de programmation, voici quelques exemples de situation " ;
00192 echo " pour expliciter les grands principes de la programmation. Vous en déduirez facilement les qualités et compétences requises " ;
00193 echo " pour savoir programmer..." ;
00194 finp() ;
00195
00196
00197 ## -------------------------------------------------------------------------------------------
00198
00199 $sous++ ; h3("$numRub".".$sous Programmer, c'est réfléchir et organiser") ;
00200
00201 ## -------------------------------------------------------------------------------------------
00202
00203 blockquote() ;
00204
00205 p("texte") ;
00206 echo "Imaginons que nous cherchions ce qu'on nomme ".b("maximum")." d'une série de valeurs, c'est-à-dire la plus " ;
00207 echo " grande valeur. " ;
00208 finp() ;
00209
00210 p("texte") ;
00211 echo "Prenons par exemple les valeurs ".b("1 8 2 5 8 7 8").". " ;
00212 echo " Je suis sûr que vous avez trouvé le maximum qui est ".b("8").". " ;
00213 echo " Mais de quel ".b("8")." s'agit-il ?" ;
00214 echo " Est-ce le premier ?" ;
00215 echo " Le second ?" ;
00216 echo " Le dernier ?" ;
00217 finp() ;
00218
00219 p("texte") ;
00220 echo "Et comment avez-vous fait ? Avez-vous passé en revue toutes les valeurs à " ;
00221 echo " partir du début ? Ou à partir de la fin ?" ;
00222 finp() ;
00223
00224 p("texte") ;
00225 echo "Et s'il s'agissait de pourcentages, vu que le maximum est 100 %, est-ce que cela " ;
00226 echo " changerait quelque chose à votre façon de chercher le maximum ?" ;
00227 finp() ;
00228
00229 p("texte") ;
00230 echo "Imaginons maintenant que nous voulions le maximum, le nombre de fois où il apparait et la (ou les) positions où il apparait. " ;
00231 echo " Sachant que la liste des valeurs est longue pour un humain (disons une centaine de valeurs), sauriez-vous résoudre ce " ;
00232 echo " problème en ne passant en revue la liste qu'une seule fois ?" ;
00233 finp() ;
00234
00235 p("texte") ;
00236 echo "Programmer, c'est aussi se poser ce genre de questions. En cas de très grandes listes pour " ;
00237 echo " l'ordinateur (par exemple si chaque valeur est obtenue au bout d'un long calcul), il faut " ;
00238 echo rouge("réfléchir")." pour trouver une méthode rapide. " ;
00239 echo " Passer en revue la liste une première fois pour trouver le maximum et la passer en revue une seconde fois " ;
00240 echo " pour calculer le nombre d'occurences et les positions du maximum est une méthode simple mais non rapide. " ;
00241 finp() ;
00242
00243 p("texte") ;
00244 echo "L'usage veut donc qu'avant de commencer à programmer on réfléchisse au problème, aux entrées et aux sorties, " ;
00245 echo " aux fonctionnalités de ce qu'on veut faire, aux durées possibles et prévoir en retour ce qu'on va programmer... " ;
00246 finp() ;
00247
00248 finblockquote() ;
00249
00250 ## -------------------------------------------------------------------------------------------
00251
00252 $sous++ ; h3("$numRub".".$sous Programmer, c'est choisir et expliciter ses choix") ;
00253
00254 ## -------------------------------------------------------------------------------------------
00255
00256 blockquote() ;
00257
00258 p("texte") ;
00259 echo "Voici un exemple classique qui fait partie de la programmation traditionnelle :" ;
00260 echo " construire le nom d'un fichier de sortie à partir d'un fichier d'entrée. " ;
00261 echo " Par exemple on veut, à partir du fichier ".bleu("serie35.xls")." construire le fichier ".bleu("serie35.txt") ;
00262 echo " ou encore, à partir de ".vert("serie_1.manip2.rep036.xls")." construire ".vert("serie_1.manip2.rep036.txt").". " ;
00263 finp() ;
00264
00265 p("texte") ;
00266 echo "Vous voyez certainement ce qu'il faut faire : repérer le \"bon\" point qui indique la fin du nom de fichier " ;
00267 echo " (ce n'est donc pas le premier point qu'on rencontre dans le nom de fichier, mais plutôt le dernier), puis " ;
00268 echo " extraire la partie avant ce point et rajouter ".b("txt")." ou ".b(".txt")." suivant qu'on a déjà extrait le point ou non. " ;
00269 finp() ;
00270
00271 p("texte") ;
00272 echo " Si les méthodes ".em(vert("extraire la première partie avec le point"))." et ".em(vert("sans le point")) ;
00273 echo " sont sans doute équivalentes en terme de simplicité et de vitesse, " ;
00274 echo " quelle est la meilleure méthode ? Et selon quels critères ?" ;
00275 echo " Une fois que vous aurez trouvé ce qui est la meilleure méthode pour vous (et vos fichiers) -- ce qui n'est peut-être pas " ;
00276 echo " la même meilleure méthode que pour vos collègues -- il faut le noter, documenter ce choix pour éviter de se poser la " ;
00277 echo " question à nouveau et ".b("toujours s'y tenir").", ce qui peut se faire en écrivant un sous-programme qui réalise ce traitement." ;
00278 finp() ;
00279
00280 finblockquote() ;
00281
00282 ## -------------------------------------------------------------------------------------------
00283
00284 $sous++ ; h3("$numRub".".$sous Programmer, c'est tester, prévoir et valider") ;
00285
00286 ## -------------------------------------------------------------------------------------------
00287
00288 blockquote() ;
00289
00290 p("texte") ;
00291 echo "Reprenons l'exemple précédent de construction d'un nom de fichier en sortie. Nous avions basé notre " ;
00292 echo " analyse sur le fait qu'il y avait un point en fin de nom de fichier d'entrée. Et si ce n'était pas le cas ?" ;
00293 echo " C'est ce qui risque d'arriver non pas en ligne, si on tape le nom du fichier, mais si le nom du fichier d'entrée " ;
00294 echo " a par exemple été mal construit par un autre programme. Que fait la méthode précédente ? " ;
00295 finp() ;
00296
00297 p("texte") ;
00298 echo "La réponse dépend de la façon dont vous avez détecté le point. Certaines fonctions renvoient, lorsque le point n'est pas " ;
00299 echo" trouvé, la valeur -1, d'autres une valeur égale à \"1 de plus que la longueur du nom de fichier\". " ;
00300 echo " Ces deux choix se valent, le plus important est d'y avoir pensé car ce qu'il faut faire dans ce cas dépend " ;
00301 echo " de la valeur renvoyée. " ;
00302 finp() ;
00303
00304 p("texte") ;
00305 echo "Nous essaierons, dans le cadre des exercices présentés, de prévoir les cas usuels classiques d'erreur (fichier non présent " ;
00306 echo " ou faute de frappe, liste vide de valeurs...) afin d'avoir des programmes dits ".b("robustes")." et ".b("fiables").". " ;
00307 finp() ;
00308
00309 p("texte") ;
00310 echo "Cela signifie qu'en conséquence il faudra tester différents cas classiques afin de valider le \"bon\" comportement " ;
00311 echo " de nos programmes dans les conditions normales d'application et de gérer les cas exceptionnels. " ;
00312 finp() ;
00313
00314 p("texte") ;
00315 echo " En particulier, il faudra réfléchir, organiser et prévoir ce qu'on fait par exemple si un fichier n'est pas vu alors " ;
00316 echo " qu'on traite une liste de fichiers. Interrompre le programme pour demander un nouveau nom est peut-être inadapté, " ;
00317 echo " tout arrêter est sans doute trop brutal, se contenter d'afficher un message d'erreur est certainement maladroit " ;
00318 echo " parce qu'il risque de disparaitre si la " ;
00319 echo " liste des fichiers à traiter est longue..." ;
00320 finp() ;
00321
00322 finblockquote() ;
00323
00324 ## -------------------------------------------------------------------------------------------
00325
00326 $sous++ ; h3("$numRub".".$sous Programmer demande de l'endurance, de la précision et de la rigueur") ;
00327
00328 ## -------------------------------------------------------------------------------------------
00329
00330 blockquote() ;
00331
00332 p("texte") ;
00333 echo "Au vu des situations présentées ci-dessus, il est clair que la programmation n'est pas au départ " ;
00334 echo " une partie de plaisir puisqu'il faut réfléchir, trouver une \"bonne\" solution -- souvent un compromis entre " ;
00335 echo " simplicité et vitesse d'exécution, penser aux erreurs possibles... " ;
00336 finp() ;
00337
00338 p("texte") ;
00339 echo "Par contre, c'est au final une réelle joie que d'avoir un programme qui \"tourne\" sans \"bugger\" ou \"boucler\", " ;
00340 echo " que d'obtenir presque ".b("automatiquement")." toute une série de résultats et de fichiers sans avoir de nombreux " ;
00341 echo " copier/coller ou de fastidieuses manipulations à faire et à refaire, de fournir à la communauté un " ;
00342 echo " programme qui peut aider d'autres collègues et faire gagner ainsi beaucoup de temps, cette denrée rare..." ;
00343 finp() ;
00344
00345 ## -------------------------------------------------------------------------------------------
00346
00347 finblockquote() ;
00348
00349 finblockquote() ;
00350
00351 #######################################################################################################################
00352
00353 $tdmCRLM1->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Spécificités du langage $R
00354
00355 ## -------------------------------------------------------------------------------------------
00356
00357 blockquote() ;
00358
00359 p("texte") ;
00360 echo "La programmation en $R ressemble au départ à la programmation traditionnelle. " ;
00361 echo " Ce qui change beaucoup, c'est principalement le fait que $R est ".rouge("vectoriel").", qu'on utilise un " ;
00362 echo " environnement qui sauvegarde les variables et qu'il y a des milliers de fonctions de base et des milliers " ;
00363 echo " de fonctions complémentaires disponibles dans des ".b("packages").". " ;
00364 echo " Du coup, de nombreuses actions (trier, calculer, tracer...) sont soit élémentaires soit déjà programmées." ;
00365 finp() ;
00366
00367 finblockquote() ;
00368
00369 #######################################################################################################################
00370 #
00371 # progic2
00372 #
00373 #######################################################################################################################
00374
00375 $numcours = 2 ; partie($numcours) ; pvide() ;
00376 $rubrique = 0 ;
00377 $rubriques2 = array() ;
00378 $rubrique++ ; $rubriques2[$rubrique] = "Variables simples et affectations" ;
00379 $rubrique++ ; $rubriques2[$rubrique] = "Structures de données et affectations en $R" ;
00380 $rubrique++ ; $rubriques2[$rubrique] = "Autres \"objets\" en $R";
00381 $rubrique++ ; $rubriques2[$rubrique] = "Affichage des variables en $R";
00382 $rubrique++ ; $rubriques2[$rubrique] = "Spécificités du langage $R";
00383
00384 $tdmCRLM2 = new tdm($rubriques2) ;
00385 $tdmCRLM2->titre() ;
00386 $tdmCRLM2->menu("oui","oui","nou","p$numcours") ;
00387
00388 $numRub = 0 ;
00389
00390 #######################################################################################################################
00391
00392 $tdmCRLM2->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Variables simples et affectations
00393
00394 ## -------------------------------------------------------------------------------------------
00395
00396 blockquote() ;
00397
00398 p("texte") ;
00399 echo "Une ".b("variable")." est semblable à une boite dotée d'un nom (ou ".em("identifiant").") " ;
00400 echo " qui contient une valeur (nommée aussi ".em("contenu de la variable")."). " ;
00401 echo " Réaliser une ".b("affectation").", c'est mettre une valeur dans une variable, " ;
00402 echo " qu'il s'agisse d'une valeur numérique ou caractère ou autre. " ;
00403 echo " Mettre une valeur dans une variable pour la première fois se nomme ".b("initialiser")." la variable. " ;
00404 echo " Contrairement à d'autres langages de programmation il n'y a pas besoin en $R de prévenir (".em("\"déclarer\"") ;
00405 echo " ou \"typer\" cette variable) en prévenant ce qu'elle va contenir, un nombre, du texte, etc. " ;
00406 echo " On utilise en $R les symboles accolés tiret et supérieur (ce qui ressemble un peu à une flèche) pour indiquer " ;
00407 echo " le contenu et la variable. " ;
00408 echo " Deux syntaxes sont possibles en $R :" ;
00409 finp() ;
00410
00411 pre_fichier("syntaxe1.txt","cadre") ;
00412
00413
00414 p("texte") ;
00415 echo "La première forme avec d'abord le nom de la variable est la plus classique mais la seconde est la plus explicite " ;
00416 echo " et sans doute la plus compréhensible. " ;
00417 echo " La machine commence toujours par évaluer (calculer) la partie du coté du tiret de la flèche, ce qui explique que l'instruction " ;
00418 finp() ;
00419
00420 pre_fichier("syntaxe2.txt","cadre") ;
00421
00422
00423 p("texte") ;
00424 echo "a un sens qui signifie ".b("rajouter un à la variable").", ce qui se dit ".b("incrémenter la variable").". " ;
00425 finp() ;
00426
00427 p("texte") ;
00428 echo "Lorsque la machine exécute \"le code\" (les instructions), elle procéde ".b("en séquence")." c'est-à-dire qu'elle exécute " ;
00429 echo " les instructions les unes à la suite des autres. C'est un peu un «jeu de piste» que de trouver ce que " ;
00430 echo " fait la machine lorsqu'on lit les instructions. Ainsi avec le code ";
00431 finp() ;
00432
00433 pre_fichier("syntaxe3.txt","cadre") ;
00434
00435
00436 p("texte") ;
00437 echo " on trouve 3 dans la variable ".vert("a")." et 6 dans la variable ".vert("b").", ce qui se nomme " ;
00438 echo b("permuter les variables")." alors qu'avec le code " ;
00439 finp() ;
00440
00441 pre_fichier("syntaxe4.txt","cadre") ;
00442
00443 p("texte") ;
00444 echo " on n'obtient rien de particulier (ou, plutôt, si, on perd la valeur de ".vert("a")."). " ;
00445 finp() ;
00446
00447 p("texte") ;
00448 echo rouge("Conclusion ").":" ;
00449 echo " il faut être très prudent(e), bien se relire, bien tout vérifier car on a vite fait de se tromper, " ;
00450 echo " surtout si on tape vite sur le clavier. " ;
00451 finp() ;
00452
00453 p("texte") ;
00454 echo "Pour ceux et celles qui n'ont pas compris le détail de la permutation des variables, voici les explications " ;
00455 echo " écrites directement dans le code à l'aide de commentaires repérés par le symbole dièse (#). La machine ne tient pas " ;
00456 echo " compte du dièse et de ce qui le suit. " ;
00457 echo " Il est conseilé de mettre «".em("suffisamment")."» de commentaires afin de pouvoir se relire et que les " ;
00458 echo " autres personnes qui lisent le code puissent le comprendre." ;
00459 finp() ;
00460
00461 pre_fichier("syntaxe5.txt","cadre") ;
00462
00463 p("texte") ;
00464 echo "Il existe bien sûr des solutions plus simples, plus générales pour réaliser cette permutation. " ;
00465 #echo " Voir l'".href("progie2.php?solutions=0#tdm1","exercice 1")."." ;
00466 finp() ;
00467
00468 p("texte") ;
00469 echo "Le choix du nom des variables (en particulier le nombre de lettres de l'identifiant) et la façon de les écrire ne sont pas " ;
00470 echo " imposés, mais il existe plusieurs méthodes et surtout quelques conseils de bon sens. " ;
00471 #echo " Voir l'".href("progie2.php?solutions=0#tdm2","exercice 2")."." ;
00472 finp() ;
00473
00474
00475 finblockquote() ;
00476
00477 #######################################################################################################################
00478
00479 $tdmCRLM2->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Structures de données et affectations en $R
00480
00481 ## -------------------------------------------------------------------------------------------
00482
00483 blockquote() ;
00484
00485 # vecteurs et listes
00486
00487 p("texte") ;
00488 echo "$R est un langage ".rouge("vectoriel") ;
00489 echo " ce qui signifie que les ".bleu("vecteurs")." sont les éléments de base du langage. " ;
00490 echo " On peut créer des vecteurs de différentes façons, par exemple avec " ;
00491 echo lafonction("c") ;
00492 echo ", " ;
00493 echo lafonction("seq") ;
00494 echo ", " ;
00495 echo lafonction("vector") ;
00496 echo ", " ;
00497 echo lafonction("rep") ;
00498 echo " ou son raccourci ".rouge(":")." (le symbole deux-points)... " ;
00499 echo " Grâce à " ;
00500 echo lafonction("identical") ;
00501 echo ", il est facile de vérifier que ".b("x")." et ".b("c(x)")." représentent le même objet. " ;
00502 echo " Le nombre d'éléments d'un vecteur se nomme sa ".b("longueur")." et s'obtient en $R à l'aide de " ;
00503 echo lafonction("length") ;
00504 echo "." ;
00505 finp() ;
00506
00507 pre_fichier("syntaxe6.txt","cadre") ;
00508
00509
00510 p("texte") ;
00511 echo "En $R, ".rouge("a:b")." correspond aux vecteurs des entiers qui vont de ".rouge("a")." à ".rouge("b").". " ;
00512 echo " Voici quelques exemples :" ;
00513 finp() ;
00514
00515 pre_fichier("syntaxe7.txt","cadre") ;
00516
00517
00518 p("texte") ;
00519 echo "Comme le montrent les trois derniers exemples, $R connait le ".b("calcul vectoriel")." :" ;
00520 echo " additionner 1 à un vecteur, c'est ajouter 1 à chacun des éléments du vecteur. De même, $R sait " ;
00521 echo " additionner ".em(b("naturellement"))." des vecteurs de même longueur, les multiplier... " ;
00522 echo " Il faut donc ".bleu("impérativement")." utiliser des parenthèses en cas de doute sur une opération ou réaliser une " ;
00523 echo " affectation supplémentaire pour obtenir un ".b("code lisible")." :" ;
00524 finp() ;
00525
00526 pre_fichier("syntaxe8.txt","cadre") ;
00527
00528 p("texte") ;
00529 echo "Maitriser la notation deux-points et les opérations vectorielles élémentaires est très important parce que " ;
00530 echo" cela permet d'effectuer de nombreux calculs et de générer de nombreuses valeurs ".b("à moindre frappe").". " ;
00531 #echo " Voir l'".href("progie2.php?solutions=0#tdm3","exercice 3")."." ;
00532 finp() ;
00533
00534 p("texte") ;
00535 echo "En plus des vecteurs, $R dispose des ".bleu("listes")." comme élements de base. " ;
00536 echo " Une liste nommée (nous ne conseillons pas d'utiliser des listes non nommées) se définit via le mot " ;
00537 echo " anglais ".b(hrrr("list"))." -- on s'en serait douté ! On accède aux éléments d'une liste nommée via leur nom " ;
00538 echo " et le symbole ".b("\$")." (dollar). " ;
00539 echo " Le nombre d'éléments d'une liste se nomme sa ".b("longueur")." et s'obtient en $R à l'aide de " ;
00540 echo lafonction("length") ;
00541 echo " mais attention car une liste peut contenir plein de choses, des vecteurs, d'autres listes, etc. " ;
00542 echo " Voici quelques exemple qui se veulent explicites :" ;
00543 finp() ;
00544
00545 pre_fichier("syntaxe9.txt","cadre") ;
00546
00547
00548 finblockquote() ;
00549
00550 #######################################################################################################################
00551
00552 $tdmCRLM2->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # "Autres \"objets\" en $R
00553
00554 ## -------------------------------------------------------------------------------------------
00555
00556 blockquote() ;
00557
00558 # matrices et dataframes
00559
00560 p("texte") ;
00561 echo "$R dispose aussi de deux structures de données très importantes issues des vecteurs et des listes :" ;
00562 echo " ce sont les ".b("matrices")." et les ".b("data frames")." qui permettent de représenter respectivement des tableaux " ;
00563 echo " homogènes et hétérogènes classiques avec des lignes et des colonnes. " ;
00564 echo " Nous y reviendrons plus tard." ;
00565 echo " Signalons aussi qu'il existe des tableaux généraux (".b("array").") mais dont on se passe la plupart du temps !" ;
00566 finp() ;
00567
00568 p("texte") ;
00569 echo "Pour connaitre la nature d'on objet, on peut utiliser ".lafonction("class")." :" ;
00570 finp() ;
00571
00572 pre_fichier("class.txt","cadre") ;
00573
00574 p("texte") ;
00575 echo "$R a aussi des valeurs \"spéciales\" nommées ".b("NA").", et ".b("NULL")." dont nous reparlerons plus tard, comme les résultats " ;
00576 echo b("Inf").", ". b("NAN")." et ".b("<NA>").". " ;
00577 finp() ;
00578
00579
00580 p("texte") ;
00581 echo "Pour les plus impatient(e)s, le lien sous ces mots dans le tableau suivant mène à l'aide de $R pour ces valeurs :" ;
00582 finp() ;
00583
00584 blockquote() ;
00585 table(1,8,"collapse bleu_pastel") ;
00586 entetesTableau("mot signification","jaune_pastel") ;
00587
00588 tr() ;
00589 td("") ;
00590 nbsp() ;
00591 echo href("http://finzi.psych.upenn.edu/R/library/base/html/NA.html","NA","gvertf") ;
00592 nbsp() ;
00593 fintd() ;
00594 td() ;
00595 echo "Not Available" ;
00596 fintd() ;
00597 fintr() ;
00598
00599 tr() ;
00600 td() ;
00601 nbsp() ;
00602 echo href("http://finzi.psych.upenn.edu/R/library/base/html/NULL.html","NULL","gvertf") ;
00603 nbsp() ;
00604 fintd() ;
00605 td() ;
00606 echo "Rien (!)" ;
00607 fintd() ;
00608 fintr() ;
00609
00610 tr() ;
00611 td() ;
00612 nbsp() ;
00613 echo href("http://finzi.psych.upenn.edu/R/library/base/html/is.finite.html","NAN","gvertf") ;
00614 nbsp() ;
00615 fintd() ;
00616 td() ;
00617 echo "Not a number (pas un nombre)" ;
00618 fintd() ;
00619 fintr() ;
00620
00621 tr() ;
00622 td() ;
00623 nbsp() ;
00624 echo href("http://finzi.psych.upenn.edu/R/library/base/html/is.finite.html","Inf","gvertf") ;
00625 nbsp() ;
00626 fintd() ;
00627 td() ;
00628 echo "Infini" ;
00629 fintd() ;
00630 fintr() ;
00631
00632 fintable() ;
00633 finblockquote() ;
00634
00635 p() ;
00636 #echo " Voir l'".href("progie2.php?solutions=0#tdm4","exercice 4")."." ;
00637 finp() ;
00638
00639 finblockquote() ;
00640
00641 #######################################################################################################################
00642
00643 $tdmCRLM2->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Affichage des variables en R
00644
00645 ## -------------------------------------------------------------------------------------------
00646
00647 # print cat paste et sprintf
00648
00649 blockquote() ;
00650
00651 p("texte") ;
00652 echo "On dispose de deux fonctions principales pour afficher les variables :" ;
00653 echo lafonction("print") ;
00654 echo " et " ;
00655 echo lafonction("cat").". " ;
00656 echo " De plus on peut utiliser ".hrrr("paste")." et ".hrrr("sprintf") ;
00657 echo " pour respectivement concaténer des chaines ou les formater." ;
00658 echo " Voici un petit pot-pourri qui montre la puissance de ces fonctions : " ;
00659 #echo " sachant que lorsque $R affiche ".b("[nn]")." il s'agit de l'indice du premier élément affiché :" ;
00660 finp() ;
00661
00662 pre_fichier("affiche.txt","cadre") ;
00663
00664 finblockquote() ;
00665
00666 #######################################################################################################################
00667
00668 $tdmCRLM2->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Spécificités du langage R
00669
00670 ## -------------------------------------------------------------------------------------------
00671
00672 blockquote() ;
00673
00674 p("texte") ;
00675 echo "$R est un langage particulier puisqu'il est ".rouge("vectoriel").". " ;
00676 echo " Du coup, on dispose facilement de séries de valeurs et de calculs ".em("idoines")." " ;
00677 echo " et en particulier on peut appliquer à des vecteurs des fonctions statistiques et mathématiques comme " ;
00678 echo hrrr("sum").", ";
00679 echo hrrr("mean").", ";
00680 echo href("http://finzi.psych.upenn.edu/R/library/base/html/Extremes.html","min","gvertf").", " ;
00681 echo href("http://finzi.psych.upenn.edu/R/library/base/html/Extremes.html","max","gvertf")."... " ;
00682 finp() ;
00683
00684 pre_fichier("applique.txt","cadre") ;
00685
00686 p("texte") ;
00687 echo " De façon subtile, $R distingue les entiers des réels. Ainsi ".b("1")." est un réel alors que " ;
00688 echo b("1L")." est un entier. Comme ".rouge(":")." renvoie des entiers, il est normal que " ;
00689 echo b("1:2")." ne soit pas égal à ".b("c(1,2)")." mais bien à ".b("c(1L,2L)").". " ;
00690 finp() ;
00691
00692 p("texte") ;
00693 echo "Il faut aussi noter que les vecteurs sont toujours \"plats\", homogènes en type et que $R convertit sans prévenir. " ;
00694 echo " Cela peut avoir de graves conséquences :" ;
00695 finp() ;
00696
00697 pre_fichier("conversion.txt","cadre") ;
00698
00699 p("texte") ;
00700 echo "Signalons au passage que les fonctions sont des variables et qu'on peut donc les inclure dans des listes... " ;
00701 finp() ;
00702
00703 pre_fichier("foncvar.txt","cadre") ;
00704
00705 p("texte") ;
00706 echo "Enfin, il faut noter que l'affectation est aussi une fonction. La notation ".b("<-")." n'est qu'un raccourci d'écriture :" ;
00707 finp() ;
00708
00709 pre_fichier("foncaffect.txt","cadre") ;
00710
00711 finblockquote() ;
00712
00713 #######################################################################################################################
00714 #
00715 # progic3
00716 #
00717 #######################################################################################################################
00718
00719 $numcours = 3 ; partie($numcours) ; pvide() ;
00720 $rubrique = 0 ;
00721 $rubriques3 = array() ;
00722 $rubrique++ ; $rubriques3[$rubrique] = "Valeurs logiques et tests en $R" ;
00723 $rubrique++ ; $rubriques3[$rubrique] = "Filtrage vectoriel" ;
00724 $rubrique++ ; $rubriques3[$rubrique] = "Applications aux matrices et ".em("dataframes") ;
00725 $rubrique++ ; $rubriques3[$rubrique] = "Spécificités du langage $R";
00726
00727 $tdmCRLM3 = new tdm($rubriques3) ;
00728 $tdmCRLM3->titre() ;
00729 $tdmCRLM3->menu("oui","oui","nou","p$numcours") ;
00730
00731 $numRub = 0 ;
00732
00733 #######################################################################################################################
00734
00735 $tdmCRLM3->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Valeurs logiques et tests en R
00736
00737 ## -------------------------------------------------------------------------------------------
00738
00739 blockquote() ;
00740
00741 p("texte") ;
00742 echo "$R dispose de deux valeurs logiques nommées ".b("FALSE")." et ".b("TRUE")." qui valent numériquement 0 et 1. " ;
00743 echo " Les opérateurs qui renvoient des valeurs logiques sont très classiquement ".b("<")." et ".b(">").". " ;
00744 echo " Il faut leur adjoindre ".b("<=")." et ".b(">=")." et aussi ".b("==")." (bien noter qu'il y a deux signes \"égal\") " ;
00745 echo " pour tester l'égalité. Pour des variables simples, " ;
00746 echo " les connecteurs usuels nommés ".b("NON").", ".b("ET").", ".b("OU")." s'écrivent respectivement " ;
00747 echo b("!").", ".b("&").", ".b("|").". Il est très fortement conseillé d'utiliser des parenthèses pour séparer ces comparaisons logiques. " ;
00748 echo " Voici quelques exemples d'utilisation :" ;
00749 finp() ;
00750
00751 pre_fichier("tests1.txt","cadre") ;
00752
00753 p("texte") ;
00754 echo "Pour réaliser un test logique, on utilise une structure algorithmique dite d'alternative " ;
00755 echo " qui, en fonction d'une condition (opération à résultat logique), effectue une bloc d'instructions. " ;
00756 echo " Voici les deux formes algorithmiques, nommées respectivement SI_ALORS et SI_ALORS_SINON :" ;
00757 finp() ;
00758
00759 pre_fichier("tests2.txt","cadre") ;
00760
00761 p("texte") ;
00762 echo "La traduction en $R se fait à l'aide des mots ".b("if").", ".b("else")." et des accolades " ;
00763 echo b("{")." et ".b("}")." pour délimiter les blocs d'instruction. De telles structures permettent donc " ;
00764 echo " de ".rouge("modifier l'exécution en séquence des instructions").". " ;
00765 finp() ;
00766
00767 pre_fichier("tests3.txt","cadre") ;
00768
00769 p("texte") ;
00770 echo "Voici deux exemples en $R. " ;
00771 echo " On remarquera que nous avons (ce qui est très fortement conseillé) commenté les " ;
00772 echo " fins de SI. " ;
00773 finp() ;
00774
00775 pre_fichier("tests4.txt","cadre") ;
00776
00777 p("texte") ;
00778 echo "L'instruction ".b("stop")." en $R permet de quitter le script en cours. Cela " ;
00779 echo " peut se révéler utile, par exemple si le fichier que l'on veut traiter n'est pas trouvé (noter le mot " ;
00780 echo b("si")." dans cette phrase). Voici comment s'en servir :" ;
00781 finp() ;
00782
00783 pre_fichier("tests5.txt","cadre") ;
00784
00785 p("texte") ;
00786 echo "La valeur ".b("NA")." de $R qui signifie ".em("Not Available").", soit ".b("Non Accessible")." en français est " ;
00787 echo " aussi une valeur logique ce qui complique les cas à tester :" ;
00788 finp() ;
00789
00790 pre_fichier("testsna.r","cadre") ;
00791
00792 finblockquote() ;
00793
00794 #######################################################################################################################
00795
00796 $tdmCRLM3->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Filtrage vectoriel
00797
00798 ## -------------------------------------------------------------------------------------------
00799
00800 blockquote() ;
00801
00802 p("texte") ;
00803 echo "$R est beaucoup plus puissant avec les tests logiques qu'on ne l'imagine " ;
00804 echo " car on peut coupler l'indexation avec ces tests " ;
00805 echo " et donc réaliser des ".ghRouge(em("affectations conditionnelles")).". " ;
00806 finp() ;
00807
00808 p("texte") ;
00809 echo " Pour accéder à un élément dans un vecteur, " ;
00810 echo " $R fournit la notation \"crochets\" : ainsi ".b("x[k]")." correspond à l'élément numéro ".b("k")." sachant que, " ;
00811 echo " contrairement à la plupart des autres langages de programmation, $R commence la numérotation à 1. Donc ".b("x[0]")." -- qui existe par ailleurs " ;
00812 echo " en $R -- ne correspond pas au premier élément de ".b("x")."." ;
00813 finp() ;
00814
00815 p("texte") ;
00816 echo " La notation crochets ou ".b("indexation")." permet de spécifier plusieurs éléments. Ainsi ".b("[1:n]")." correspond aux ".b("n")." premiers éléments. " ;
00817 echo " Un indice entier mais négatif signifie ".b("tout sauf cet indice")." donc " ;
00818 echo b("(1:5)[ - c(3,4) ]")." renvoie ".b("1 2 5").". " ;
00819 finp() ;
00820
00821 p("texte") ;
00822 echo "Lorsqu'on fournit entre crochets pour une variable de type vecteur un vecteur de même longueur que cette variable composé de 0 et de 1, " ;
00823 echo " $R extrait les valeurs correspondant à 1. Par exemple ".b("(1:3)[ c(0,1,0) ]")." renvoie ".b("2").". " ;
00824 echo " Comme nous avons expliqué que les valeurs logiques FALSE et TRUE valent numériquement 0 et 1, il est facile de comprendre que " ;
00825 echo " $R fournit un mécanisme de ".b("filtrage")." très puissant avec les expressions logiques vectorielles. " ;
00826 finp() ;
00827
00828 p("texte") ;
00829 #echo " En mode vectoriel, il faut utiliser ".b("&&")." et ".b("||")." pour effectuer des ET et des OU. " ;
00830 echo " Voici des exemples :" ;
00831 finp() ;
00832
00833 pre_fichier("tests6.txt","cadre") ;
00834
00835 finblockquote() ;
00836
00837 #######################################################################################################################
00838
00839 $tdmCRLM3->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Applications aux matrices et dataframes
00840
00841 ## -------------------------------------------------------------------------------------------
00842
00843 blockquote() ;
00844
00845 p("texte") ;
00846 echo "En plus des vecteurs, $R dispose de deux structures de données nommées " ;
00847 echo b("matrix")." et ".b("data frame")." qui définissent des ".bleu("tableaux rectangulaires"). " avec des " ;
00848 echo vert("lignes")." et des ".vert("colonnes").". Il y a toutefois des grandes différences entre ces deux structures. " ;
00849 echo " Les matrices sont homogènes en type et les lignes et les colonnes y sont équivalentes en fonctionnement alors que les " ;
00850 echo " data frames sont des listes particulières : les éléments de la liste sont les colonnes du tableau, avec la contrainte " ;
00851 echo " que toutes les colonnes doivent avoir le même nombre d'éléments. Un data frame est donc particulièrement adapté " ;
00852 echo " à contenir un fichier de données pour des études statistiques, avec des colonnes de types éventuellement différents. " ;
00853 finp() ;
00854
00855 p("texte") ;
00856 echo " Toutes les " ;
00857 echo " fonctions de $R qui lisent des fichiers comme " ;
00858 echo lafonction("read.table","utils").", ";
00859 echo lafonction("read.xls","gdata")." (du package ".hrrp("gdata").") " ;
00860 echo " renvoient des data frames." ;
00861 finp() ;
00862
00863 p("texte") ;
00864 echo "Les conditions logiques et le filtrage vectoriel permettent d'extraire facilement des sous-ensembles de ces tableaux " ;
00865 echo " de données comme le montrent les exemples ci-dessous" ;
00866 echo " pour le fichier de données ".href("elf.txt")." :" ;
00867 finp() ;
00868
00869 pre_fichier("extr.txt","cadre") ;
00870
00871 finblockquote() ;
00872
00873 #######################################################################################################################
00874
00875 $tdmCRLM3->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Spécificités du langage $R
00876
00877 ## -------------------------------------------------------------------------------------------
00878
00879 blockquote() ;
00880
00881 p("texte") ;
00882 echo "En $R, les indices commencent à 1. C'est une révolution par rapport aux autres langages de programmation " ;
00883 echo " qui ne comptent pas en position mais en décalage (".em("offset").") à partir du début du tableau. Cela facilite " ;
00884 echo " beaucoup les calculs. " ;
00885 finp() ;
00886
00887 p("texte") ;
00888 echo "A cause de la valeur NA -- qui est spécifique à R, la comparaison entre valeurs en $R est compliquée : " ;
00889 finp() ;
00890
00891 pre_fichier("natables.txt","cadre") ;
00892
00893 p("texte") ;
00894 echo "Heureusement il y a de nombreuses fonctions comme " ;
00895 echo hrrr("NA","","is.na()") ;
00896 echo " et " ;
00897 echo hrrr("na.fail","stats","na.omit()") ;
00898 echo " qui permettent de détecter et d'enlever ces valeurs NA. On trouve aussi, comme pour " ;
00899 echo lafonction("sum").", une option ".b("na.rm=TRUE")." qui enlève (localement) ces valeurs NA." ;
00900 finp() ;
00901
00902 p("texte") ;
00903 echo "$R dispose de nombreuses fonctions logiques :" ;
00904 finp() ;
00905
00906 pre_fichier("is.txt","cadre") ;
00907
00908 p("texte") ;
00909 echo "Comme nous l'avons dit précédemment, les structures de données de base sont les vecteurs et les listes. Il faut " ;
00910 echo " néanmoins bien connaitre les data frames et les matrices (et leurs \"pièges\") pour écrire de " ;
00911 echo " \"beaux\" programmes concis :" ;
00912 finp() ;
00913
00914 pre_fichier("isdf.txt","cadre") ;
00915
00916
00917 p("texte") ;
00918 echo "Il faut noter que $R permet d'affecter des parties de vecteur grâce à l'indexation et au filtrage logique. " ;
00919 echo " Ainsi l'instruction :" ;
00920 finp() ;
00921
00922 pre_fichier("remp.txt","cadre") ;
00923
00924
00925 p("texte") ;
00926 echo " vient remplacer dans ".("v")." toutes les valeurs strictements inférieures à 5 par 0." ;
00927 finp() ;
00928
00929 p("texte") ;
00930 echo "Enfin, il existe sous $R plusieurs fonctions qui évitent de faire des tests logiques pour trouver des " ;
00931 echo " valeurs, les remplacer... comme les fonctions " ;
00932 echo hrrr("ifelse").", " ;
00933 echo hrrr("which").", " ;
00934 echo hrrr("grep").", " ;
00935 echo hrrr("grep","base","sub()")."... " ;
00936 finp() ;
00937
00938 #pre_fichier("grepwhich.txt","cadre") ;
00939
00940 finblockquote() ;
00941
00942 #######################################################################################################################
00943 #
00944 # progic4
00945 #
00946 #######################################################################################################################
00947
00948 $numcours = 4 ; partie($numcours) ; pvide() ;
00949 $rubrique = 0 ;
00950 $rubriques4 = array() ;
00951 $rubrique++ ; $rubriques4[$rubrique] = "Boucles \"TANT QUE\"" ;
00952 $rubrique++ ; $rubriques4[$rubrique] = "Boucles \"POUR\"" ;
00953 $rubrique++ ; $rubriques4[$rubrique] = "Boucles \"REPETER JUSQU'A\"" ;
00954 $rubrique++ ; $rubriques4[$rubrique] = "Itérations et sorties de boucles" ;
00955 $rubrique++ ; $rubriques4[$rubrique] = "Imbrications, itérations et sorties de boucles" ;
00956 $rubrique++ ; $rubriques4[$rubrique] = "Exemples de boucles usuelles (mais potentiellement lentes) en $R";
00957 $rubrique++ ; $rubriques4[$rubrique] = "Comment et pourquoi éviter les boucles pour en $R";
00958 $rubrique++ ; $rubriques4[$rubrique] = "Spécificités du langage $R";
00959
00960 $tdmCRLM4 = new tdm($rubriques4) ;
00961 $tdmCRLM4->titre() ;
00962 $tdmCRLM4->menu("oui","oui","nou","p$numcours") ;
00963
00964 $numRub = 0 ;
00965
00966 #######################################################################################################################
00967
00968 $tdmCRLM4->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Boucles "tant que"
00969
00970 ## -------------------------------------------------------------------------------------------
00971
00972 blockquote() ;
00973
00974 p("texte") ;
00975 echo "La boucle TANT QUE (".b("while")." en anglais) est un peu comme une structure ".b("si")." répétitive. ";
00976 echo " Sa syntaxe algorithmique est la suivante :" ;
00977 finp() ;
00978
00979 pre_fichier("tantque1a.txt","cadre") ;
00980
00981 p("texte") ;
00982 echo "Son écriture en $R est immédiate :" ;
00983 finp() ;
00984
00985 pre_fichier("tantque1b.txt","cadre") ;
00986
00987 p("texte") ;
00988 echo "En voici un exemple :" ;
00989 finp() ;
00990
00991 pre_fichier("tantque1c.txt","cadre") ;
00992
00993 p("texte") ;
00994 echo "Il faut être ".rouge("très prudent(e)")." avec une boucle ".b("tant que")." car l'ordinateur " ;
00995 echo " peut boucler pendant un temps infini si la condition est mal écrite. Ainsi dans l'exemple " ;
00996 echo " précédent, nous avons malheureusement oublié que la machine ne doit pas aller après le dernier caractère. Supposer " ;
00997 echo " qu'un nom de fichier contient toujours un point serait une erreur de conception et le code précédent ne s'arrête " ;
00998 echo " jamais s'il n'y a pas de point dans le nom de fichier. Voici ce qu'il faut écrire pour avoir un code correct :" ;
00999 finp() ;
01000
01001 pre_fichier("tantque2.txt","cadre") ;
01002 # on peut en sortir avec break
01003
01004 finblockquote() ;
01005
01006 #######################################################################################################################
01007
01008 $tdmCRLM4->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Boucles "pour"
01009
01010 ## -------------------------------------------------------------------------------------------
01011
01012 blockquote() ;
01013
01014 p("texte") ;
01015 echo "Lorsque le nombre de répétitions est connu, que ce soit une valeur constante comme 10 ou le nombre des éléments d'un vecteur, " ;
01016 echo " on peut utiliser une autre structure répétitive, nommée boucle POUR dont voici la syntaxe algorithmique :" ;
01017 finp() ;
01018
01019 pre_fichier("pour1a.txt","cadre") ;
01020
01021 p("texte") ;
01022 echo "Là encore, son écriture en $R est immédiate :" ;
01023 finp() ;
01024
01025 pre_fichier("pour1b.txt","cadre") ;
01026
01027 p("texte") ;
01028 echo "Et un exemple peut être :" ;
01029 finp() ;
01030
01031 pre_fichier("pour1c.txt","cadre") ;
01032
01033 p("texte") ;
01034 echo "Dans les faits, $R dispose d'une boucle POUR plus générale d'itération nommée aussi ".b("for").". Voici des " ;
01035 echo " exemples :" ;
01036 finp() ;
01037
01038 pre_fichier("pour2.txt","cadre") ;
01039
01040 finblockquote() ;
01041
01042 #######################################################################################################################
01043
01044 $tdmCRLM4->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Boucles "REPETER JUSQU'A"
01045
01046 ## -------------------------------------------------------------------------------------------
01047
01048 blockquote() ;
01049
01050 p("texte") ;
01051 echo "Le troisième type de boucle disponible consiste à faire le test pour savoir \n" ;
01052 echo "si on recommence la boucle ".b("en fin de corps de boucle").". La syntaxe \n" ;
01053 echo "algorithmique est la suivante : \n" ;
01054 finp() ;
01055
01056 pre_fichier("repeter1.txt","cadre") ;
01057
01058 p("texte") ;
01059 echo "Sa traduction n'est pas immédiate en $R parce qu'on écrit seulement \n" ;
01060 finp() ;
01061
01062 pre_fichier("repeter2.r","cadre") ;
01063
01064 p("texte") ;
01065 echo "Il faut impérativement passer par ".noir("break")." ou ".noir("stop()")." pour sortir de la boucle \n" ;
01066 echo " REPETER JUSQU'A en $R. \n" ;
01067 echo "Voici un exemple d'une telle boucle en $R qui demande un nom de fichier et teste si le \n" ;
01068 echo "fichier est présent avant d'aller plus loin : \n" ;
01069 finp() ;
01070
01071 pre_fichier("repeter3.r","cadre") ;
01072
01073 p("texte") ;
01074 echo rouge("Attention : ") ;
01075 echo " il y beaucoup de fonctions $R qui dispensent d'écrire des boucles. Il est prudent de " ;
01076 echo " les apprendre parce que l'exécution des boucles en $R " ;
01077 echo " est souvent lente à cause de la gestion en mémoire des variables. " ;
01078 echo " Ainsi ".lafonction("cbind")." fournit nativement la correspondance entre indice et élément. " ;
01079 #echo " Voir les exercices pour se convaincre qu'il faut apprendre de nombreuses fonctions $R." ;
01080 finp() ;
01081
01082 finblockquote() ;
01083
01084 #######################################################################################################################
01085
01086 $tdmCRLM4->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Itérations et sorties de boucles
01087
01088 ## -------------------------------------------------------------------------------------------
01089
01090 blockquote() ;
01091
01092 p("texte") ;
01093 echo "Il peut arriver que l'on veuille sortir d'une boucle ou du script. " ;
01094 echo " Quelque soit le type de boucle, " ;
01095 echo " la fonction ".hrrr("stop")." quitte le script en cours alors que l'instruction " ;
01096 echo b("break")." permet de sortir de la boucle. On peut aussi utiliser ".b("next")." pour " ;
01097 echo " forcer la machine à passer à l'itération suivante. " ;
01098 echo " Voici des exemples :" ;
01099 finp() ;
01100
01101 pre_fichier("boucles3.ent","cadrebleu") ;
01102
01103 p("texte") ;
01104 echo "L'exécution de cette boucle aboutit aux résultats suivants :" ;
01105 finp() ;
01106
01107 pre_fichier("boucles3.sor","cadrejaune") ;
01108
01109 finblockquote() ;
01110
01111 #######################################################################################################################
01112
01113 $tdmCRLM4->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Imbrications, itérations et sorties de boucles
01114
01115 ## -------------------------------------------------------------------------------------------
01116
01117 blockquote() ;
01118
01119 p("texte") ;
01120 echo "Comme pour les tests, on peut imbriquer les boucles, éventuellement de différents \n" ;
01121 echo "types. De plus, un corps de boucle contient des instructions, donc on peut avoir \n" ;
01122 echo "une boucle à l'intérieur de la partie \"sinon\" d'un test, qui contient elle-même \n" ;
01123 echo "un autre test avec une autre boucle, etc. \n" ;
01124 finp() ;
01125
01126 p("texte") ;
01127 echo "On veillera à ne pas trop multiplier l'imbrication des structures de façon à pouvoir \n" ;
01128 echo "s'y retrouver facilement. Trois ou quatre niveaux d'imbrication (une boucle dans un \n" ;
01129 echo "test dans une boucle dans...) parait être la ".em("limite supportable de la compréhension").". \n" ;
01130 echo "Au-delà, il faut certainement recourir à un sous-programme (une fonction) pour que ce soit lisible... \n" ;
01131 finp() ;
01132
01133 p("texte") ;
01134 echo "Voici des exemples avec chacun des types de boucles qui illustrent ces points. \n" ;
01135 finp() ;
01136
01137 p("texte") ;
01138 echo "Nous commençons avec deux boucles ".b("POUR")." imbriquées pour afficher les valeurs \n" ;
01139 echo "de ".b("x^y")." inférieures à 1 million pour les nombres ".b("x")." et ".b("y")." de 1 à 10. \n" ;
01140 echo "On affiche les puissances de 1, de 2, de 3... ligne par ligne. Pour éviter de calculer \n" ;
01141 echo "mathématiquement jusqu'à quel terme on doit aller, on calcule la puissance et \n" ;
01142 echo "on ne l'affiche que si elle est inférieure à un million. \n" ;
01143 finp() ;
01144
01145 p("texte") ;
01146 echo "Voici le code $R correspondant :\n" ;
01147 finp() ;
01148
01149 pre_fichier("boucles3a.ent","cadre") ;
01150
01151 p("texte") ;
01152 echo "et le résultat de son exécution \n" ;
01153 finp() ;
01154
01155 pre_fichier("boucles3a.sor","cadre") ;
01156
01157 p("texte") ;
01158 echo "Le deuxième exemple montre comment tester une fonction à l'aide d'une réponse utilisateur \n" ;
01159 echo "via une boucle ".b("REPETER")." . \n" ;
01160 echo "Ici, nous avons pris l'exemple de la fonction qui calcule le carré pour des raisons de simplicité. \n" ;
01161 finp() ;
01162
01163 p("texte") ;
01164 echo "L'idée est ici de demander une valeur à l'utilisateur, d'afficher le résultat de la fonction et \n" ;
01165 echo "de recommencer. Nous avons décidé arbitrairement qu'entrer la valeur zéro fait sortir de la boucle. \n" ;
01166 finp() ;
01167
01168 pre_fichier("boucles3b.ent","cadre") ;
01169
01170 p("texte") ;
01171 echo "L'exécution de cette boucle aboutit aux résultats suivants, \n" ;
01172 echo "sachant que l'utilisateur a saisi 5, puis 8 puis 0 (afin d'arrêter le calcul). \n" ;
01173 finp() ;
01174
01175 pre_fichier("boucles3b.sor","cadre") ;
01176
01177 p("texte") ;
01178 echo "Comme troisième exemple, nous essayons de traiter avec une boucle ".b("TANT QUE").". \n" ;
01179 echo "tous les fichiers-texte du répertoire avec une numérotation régulière \n" ;
01180 echo "lorsqu'ils ont plus de deux lignes : \n" ;
01181 finp() ;
01182
01183 pre_fichier("boucles3c.ent","cadre") ;
01184
01185 p("texte") ;
01186 echo "Un exemple d'éxécution, avec quelques fichiers présents dans notre répertoire courant \n" ;
01187 echo "fournit l'affichage suivant. On remarquera que $R écrit ".b("Erreur")." lorsqu'on fait appel \n" ;
01188 echo "à la fonction ".noir("stop()")." . \n" ;
01189 finp() ;
01190
01191 pre_fichier("boucles3c.sor","cadre") ;
01192
01193 finblockquote() ;
01194
01195 #######################################################################################################################
01196
01197 $tdmCRLM4->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Exemples de boucles usuelles (mais lentes) en $R
01198
01199 ## -------------------------------------------------------------------------------------------
01200
01201 blockquote() ;
01202
01203 p("texte") ;
01204 echo "Nous présentons ici quelques boucles ".em("faussement susceptibles d'être utiles").". \n" ;
01205 echo "En effet, la plupart de ces boucles explicites peuvent être remplacées à moindre \n" ;
01206 echo "coût d'écriture par des fonctions de $R prévues pour cela. Ces exemples ne sont donc \n" ;
01207 echo "fournis qu'à titre d'entrainement à la lecture de boucles et ne sont pas optimisés. \n" ;
01208 finp() ;
01209
01210 p("texte") ;
01211 echo "Nous aurons l'occasion de revoir un peu plus tard comment réaliser les traitements associés à ces boucles \n" ;
01212 echo "de façon beaucoup plus \"propre et concise\" et, en tous cas, dans l'esprit de $R. \n" ;
01213 finp() ;
01214
01215 h3("$numRub.1 Traitement de toutes les colonnes d'un ".em("data frame")) ;
01216
01217 p("texte") ;
01218 echo "Il arrive assez fréquemment qu'on ait à traiter toutes les colonnes numériques quantitatives d'un data frame, \n" ;
01219 echo "par exemple pour en calculer systématiquement les moyennes, les médianes (au fait, vous vous souvenez \n" ;
01220 echo "de la différence statistique entre \n" ;
01221 echo "ces deux indicateurs de tendance centrale et pourquoi on calcule la moyenne des tailles, la médiane des poids pour les humains et \n" ;
01222 echo "pas l'inverse ?)... \n" ;
01223 finp() ;
01224
01225 p("texte") ;
01226 echo "$R fournit avec la fonction ".hrrr("nrow","","ncol()")." le nombre de colonnes d'un data frame et \n" ;
01227 echo "avec la fonction ".hrrr("names")." le nom de ces colonnes. Il pourrait être tentant d'écrire une boucle comme \n" ;
01228 finp() ;
01229
01230 pre_fichier("noallqt.r","cadre") ;
01231
01232 p("texte") ;
01233 echo "mais c'est certainement se fatiguer beaucoup, surtout si le numéro de colonne n'est pas utilisé. Il est possible \n" ;
01234 echo "en $R de passer directement en revue les noms de colonne. Au passage, nous montrons comment construire un fichier graphique \n" ;
01235 echo "de type ".noir(".png")." dont le nom reprend celui de la colonne en cours, après détection du type numérique de \n" ;
01236 echo "la colonne : \n" ;
01237 finp() ;
01238
01239 pre_fichier("allqt.r","cadre") ;
01240
01241 h3("$numRub.2 Calculs par sous-groupe") ;
01242
01243 p("texte") ;
01244 echo "Imaginons maintenant que nous voulions parcourir toutes les lignes d'un data frame pour compter (maladroitement) \n" ;
01245 echo "via le code-sexe (variable ".noir("SX").") \n" ;
01246 echo "le nombre d'hommes (".noir("SX=1").") et de femmes (".noir("SX=2")."). De façon encore plus maladroite, nous allons \n" ;
01247 echo "mettre dans la variable ".noir("agesH")." les ages des hommes \n" ;
01248 echo "et dans la variable ".noir("agesF")." les ages des femmes. ".s_span("Voici ce qu'il ne faut pas faire","grouge").", mais au moins, vous \n" ;
01249 echo "l'aurez vu et vous saurez l'éviter : \n" ;
01250 finp() ;
01251
01252 pre_fichier("pargroupes.r","cadre") ;
01253
01254 h3("$numRub.3 Traitement d'une liste de fichiers et moyenne dans un tableau") ;
01255
01256 p("texte") ;
01257 echo "On veut traiter ".b("n")." fichiers, disons " ;
01258 echo href("ficSerie01.txt").", " ;
01259 echo href("ficSerie02.txt").", " ;
01260 echo href("ficSerie03.txt")."... " ;
01261 echo " mais ce pourrait être bien sûr des fichiers Excel." ;
01262 echo " Une fois le traitement de chaque fichier effectué, on veut obtenir un tableau et un fichier .CSV résumé des traitements. " ;
01263 finp() ;
01264
01265 p("texte") ;
01266 echo "Pour notre exemple, nous allons limiter le traitement, via la fonction ".b("traiteFichier()")." à la détermination du nombre " ;
01267 echo " de lignes du fichier. Voici cette fonction :" ;
01268 finp() ;
01269
01270 pre_fichier("seriefic01.r","cadre") ;
01271
01272 p("texte") ;
01273 echo "Une fois la fonction ".b("traiteFichier()")." mise au point, on peut écrire -- même si ce n'est pas la seule et la " ;
01274 echo " meilleure solution -- une boucle pour passer en revue une série de fichiers :" ;
01275 finp() ;
01276
01277 pre_fichier("seriefic02.r","cadre") ;
01278
01279 p("texte") ;
01280 echo "Afin d'obtenir un tableau résumé, il faut prévoir un ".em("data.frame")." pour accueillir les résultats " ;
01281 echo " et modifier la fonction ".b("traiteFichier()")." pour qu'elle renvoie un résultat par fichier. On remplit " ;
01282 echo " alors au fur et à mesure la structure d'accueil dans la boucle. Une fois la boucle terminée, on peut " ;
01283 echo " afficher les résultats et les sauvegarder." ;
01284 finp() ;
01285
01286 p("texte") ;
01287 echo " Voici la fonction modifiée :" ;
01288 finp() ;
01289
01290 pre_fichier("seriefic03.r","cadre") ;
01291
01292 p("texte") ;
01293 echo " Le script qui comporte la boucle et la gestion du ".em("data.frame")." est le suivant :" ;
01294 finp() ;
01295
01296 pre_fichier("seriefic04.r","cadre") ;
01297
01298 p("texte") ;
01299 echo " Exemple d'exécution avec les fichiers cités :" ;
01300 finp() ;
01301
01302 pre_fichier("seriefic04.sor","cadre") ;
01303
01304 p("texte") ;
01305 echo " Fichier CSV produit :" ;
01306 finp() ;
01307
01308 pre_fichier("seriefic04.csv","cadre") ;
01309
01310 finblockquote() ;
01311
01312 #######################################################################################################################
01313
01314 $tdmCRLM4->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Comment et pourquoi éviter les boucles pour en R
01315
01316 ## -------------------------------------------------------------------------------------------
01317
01318 blockquote() ;
01319
01320 /*
01321 p("texte") ;
01322 echo "Les boucles, et en particulier les boucles POUR, sont souvent le moyen de réaliser des calculs " ;
01323 echo " par itération dans les langages de programmation \"classiques\". ".b("CE N'EST PAS LE CAS EN $R")." parce que " ;
01324 echo " $R est un langage ".rouge("vectoriel").". De nombreuses fonctions s'appliquent directement " ;
01325 echo " aux vecteurs, comme ".hrrr("sum")." ; pour les matrices et les listes, il faut utiliser " ;
01326 echo hrrr("apply")." et ".hrrr("lapply","","sapply").". Et il y a beaucoup d'autres fonctions prévues pour couvrir " ;
01327 echo " de nombreux autres cas, comme ".hrrr("tapply")."..." ;
01328 finp() ;
01329 */
01330
01331 p("texte") ;
01332 echo "Les boucles, et en particulier les boucles ".b("POUR").", sont souvent \n" ;
01333 echo "le moyen de réaliser des calculs par itération dans les langages \n" ;
01334 echo "de programmation \"classiques\". \n" ;
01335 finp() ;
01336
01337 p("texte") ;
01338 echo rouge("CE N'EST PAS LE CAS EN $R")." parce que \n" ;
01339 echo "$R est un langage vectoriel. De nombreuses fonctions s'appliquent \n" ;
01340 echo "directement aux vecteurs, comme ".hrrr("sum")." ; pour les matrices et les \n" ;
01341 echo "listes, il faut utiliser des fonctions comme ".hrrr("apply").", ".hrrr("lapply").", ".hrrr("lapply","","sapply()")." \n" ;
01342 echo "et ".hrrr("tapply")."... Et il y a beaucoup \n" ;
01343 echo "d'autres fonctions prévues pour couvrir de nombreux autres cas, \n" ;
01344 echo "comme ".hrrr("table").", ".hrrr("split").", ".hrrr("sweep")."... \n" ;
01345 echo " Nous verrons à la séance 6 comment on arrive à se passer des boucles et à la séance 8 comment " ;
01346 echo " optimiser des boucles si on doit vraiment les utiliser." ;
01347 finp() ;
01348
01349 finblockquote() ;
01350
01351 #######################################################################################################################
01352
01353 $tdmCRLM4->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Spécificités du langage R
01354
01355 ## -------------------------------------------------------------------------------------------
01356
01357 blockquote() ;
01358
01359 p("texte") ;
01360 echo "Une programmeuse, un programmeur C ou Java \"classique\" a l'habitude des \n" ;
01361 echo "boucles ".b("POUR")." dès qu'il s'agit de parcourir une structure. \n" ;
01362 echo "En $R , il y a beaucoup d'autres solutions et il faut du temps pour les connaitre. \n" ;
01363 echo "Ainsi, et même si ce n'est pas \"la\" bonne solution, pour obtenir la variable \n" ;
01364 echo "précédente ".noir("agesH")." qui contient les ages de hommes, on peut se contenter en \n" ;
01365 echo "$R d'utiliser le filtrage vectoriel et écrire \n" ;
01366 finp() ;
01367
01368 pre_fichier("agesh1.r","cadre") ;
01369
01370 p("texte") ;
01371 echo "ou, de façon plus lisible : \n" ;
01372 finp() ;
01373
01374 pre_fichier("agesh2.r","cadre") ;
01375
01376 p("texte") ;
01377 echo "Il est clair qu'on est loin de l'écriture d'une boucle explicite. \n" ;
01378 finp() ;
01379
01380 p("texte") ;
01381 echo "Même lorsqu'on veut utiliser des boucles ".b("POUR")." en $R il faut se méfier. \n" ;
01382 echo "Ainsi l'expression ".noir("for (i in 1:length(V))")." n'est pas une \"bonne\" écriture. En effet, si le \n" ;
01383 echo "vecteur ".noir("V")." est vide, sa longueur est nulle. Dans un langage classique, une boucle \n" ;
01384 echo "de 1 à 0 n'est pas exécutée. Pour $R, la notation ".noir("1:0")." signifie qu'on veut aller \n" ;
01385 echo "de 1 à 0 et il exécutera la boucle ! Ce qui est pire, c'est que ".noir("V[i]")." ne renverra pas \n" ;
01386 echo "alors forcément d'erreur lorsque ".noir("i")." vaut 0. Il est donc conseillé d'utiliser \n" ;
01387 echo "".noir("for (i in seq_along(V))")." pour parcourir les indices de ".noir("V")." car si ".noir("V")." est vide, \n" ;
01388 echo "$R ne rentrera pas dans la boucle avec cette écriture. \n" ;
01389 finp() ;
01390
01391 finblockquote() ;
01392
01393 #######################################################################################################################
01394 #
01395 # progic5
01396 #
01397 #######################################################################################################################
01398
01399 $numcours = 5 ; partie($numcours) ; pvide() ;
01400 $rubrique = 0 ;
01401 $rubriques5 = array() ;
01402 $rubrique++ ; $rubriques5[$rubrique] = "Définition des fonctions nommées et anonymes" ;
01403 $rubrique++ ; $rubriques5[$rubrique] = "Définition et utilisation des paramètres" ;
01404 $rubrique++ ; $rubriques5[$rubrique] = "Tests des paramètres" ;
01405 $rubrique++ ; $rubriques5[$rubrique] = "L'ellipse notée ".rouge("...") ;
01406 $rubrique++ ; $rubriques5[$rubrique] = "Quelques exemples de fonctions" ;
01407 $rubrique++ ; $rubriques5[$rubrique] = "Spécificités du langage $R";
01408
01409 $tdmCRLM5 = new tdm($rubriques5) ;
01410 $tdmCRLM5->titre() ;
01411 $tdmCRLM5->menu("oui","oui","nou","p$numcours") ;
01412
01413 $numRub = 0 ;
01414
01415 #######################################################################################################################
01416
01417 $tdmCRLM5->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Définition d'une fonction
01418
01419 ## -------------------------------------------------------------------------------------------
01420
01421 blockquote() ;
01422
01423 p("texte") ;
01424 echo "Pour définir une ".bleu("fonction nommée").", il faut réaliser une affectation avec comme partie gauche le nom de la fonction à créer, " ;
01425 echo " puis utiliser le mot ".b("function").", mettre des parenthèses, " ;
01426 echo " ajouter des paramètres s'il y en a besoin avec éventuellement des valeurs par défaut, puis écrire le corps de la fonction " ;
01427 echo " entre accolades et mettre ".b("return")." avec des parenthèses pour indiquer l'objet renvoyé, qui peut être une simple valeur " ;
01428 echo " ou quelque chose de plus complexe. Par exemple, pour inventer une fonction qui calcule le carré d'une valeur, on devrait écrire " ;
01429 finp() ;
01430
01431 entree_R("carre1.r") ;
01432
01433 p("texte") ;
01434 echo "Il est possible de raccourcir le corps de la fonction en " ;
01435 echo " omettant les accolades et en mettant comme dernière (ou comme seule) instruction le calcul à renvoyer. Ainsi, on pourrait écrire " ;
01436 finp() ;
01437
01438 entree_R("carre2.r") ;
01439
01440 p("texte") ;
01441 echo "Une écriture aussi concise est utile dans le cas d'une fonction intégrée à un appel de fonction " ;
01442 echo " ou pour une ".bleu("fonction anonyme")." (concept détaillé un peu plus bas dans cette section), mais cette " ;
01443 echo " écriture est dangereuse et «fainéante». Il vaut mieux lui préférer le code suivant : " ;
01444 finp() ;
01445
01446 entree_R("carre3.r") ;
01447
01448 p("texte") ;
01449 echo "Nous reviendrons sur ces écritures, mais un grand principe de la ".b("programmation robuste")." est qu'il faut préférer la " ;
01450 echo rouge("lisibilité").", la ".rouge("facilité de relecture")." et la " ;
01451 echo rouge("maintenance du code")." à la facilité d'écriture. Il faut viser l'écriture de programmes " ;
01452 echo bleu("robustes")." et ".bleu("lisibles")." et non pas de programmes vite tapés sur le clavier. " ;
01453 finp() ;
01454
01455 p("texte") ;
01456 echo "Pour se servir de cette fonction ".bleu("carre()")." il suffit de l'appeler là où on utiliserait le carré des valeurs. Cela peut donc être " ;
01457 echo " dans le cadre d'un calcul simple ou d'un affichage interactif (en console), dans le cadre d'une instruction d'affectation etc. " ;
01458 echo " Il n'est pas obligatoire " ;
01459 echo " ici de nommer le paramètre au niveau de l'appel, mais il vaudra mieux le faire quand il y en aura plus d'un. On peut aussi utiliser juste le nom " ;
01460 echo " de la fonction en tant que paramètre quand cela est permis. Le calcul effectué par notre fonction étant \"vectoriel\", c'est-à-dire " ;
01461 echo " applicable à une structure, notre fonction est elle-même vectorielle. Voici des exemples d'utilisation : " ;
01462 finp() ;
01463
01464 entree_R("carre4.r") ;
01465 p("texte") ;
01466 echo "Et leurs résultats : " ;
01467 finp() ;
01468 sortie_R("carre4.res") ;
01469
01470 p("texte") ;
01471 echo " Imaginons maintenant que nous voulions écrire une fonction " ;
01472 echo " ".bleu("pvalt()")." qui doit renvoyer la ".em("p-value")." du ".b("test t")." de ".em("Student") ;
01473 echo " via l'appel de la fonction ".hrrr("t.test","stats").". " ;
01474 echo " Il faut commencer par comprendre l'objet renvoyé par la fonction ".hrrr("t.test","stats").", puis trouver comment extraire la composante " ;
01475 echo " voulue, pour ensuite écrire la fonction et enfin vérifier qu'elle renvoie bien ce qu'on voulait :" ;
01476 finp() ;
01477
01478 entree_R("pval.r") ;
01479 sortie_R("pval.res") ;
01480
01481 p("texte") ;
01482 echo "Une fonction anonyme correspond à la seule partie droite de définition de la fonction. Comme on l'utilise sans affectation, elle n'a pas de nom. " ;
01483 echo " Une telle fonction s'utilise généralement comme paramètre dans un appel de fonction. " ;
01484 echo " Ainsi, pour réaliser le calcul de carrés dans une liste, on peut écrire, sans passer par une fonction ".b("carre()")." :" ;
01485 finp() ;
01486
01487 entree_R("carre5.r") ;
01488
01489 p("texte") ;
01490 echo "Si on se rend compte qu'on utilise plusieurs fois la même fonction anonyme, il est conseillé d'en faire une " ;
01491 echo "fonction nommée. Cela gagne du temps et de la maintenance de code." ;
01492 finp() ;
01493
01494 finblockquote() ;
01495
01496 #######################################################################################################################
01497
01498 $tdmCRLM5->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Définition et utilisation des paramètres
01499
01500 ## -------------------------------------------------------------------------------------------
01501
01502 blockquote() ;
01503
01504 p("texte") ;
01505 echo "Pour définir les paramètres d'une fonction, on doit impérativement les nommer. Par contre, il est " ;
01506 echo " facultatif de leur donner une valeur par défaut avec =. Mettre l'ellipse dans la définition des " ;
01507 echo " paramètres signifie que la fonction peut accepter (et transmettre) d'autres paramètres que ceux " ;
01508 echo " explicitement fournis. Voir la section 4 pour le détail sur l'ellipse. " ;
01509 finp() ;
01510
01511 p("texte") ;
01512 echo "Utiliser les paramètres dans un ordre ou dans un autre peut être plus ou moins facile à mémoriser ou à " ;
01513 echo " comprendre. On pourra s'en rendre compte si on compare les choix de l'ordre des paramètres pour le calcul de la somme des colonnes " ;
01514 echo " d'une matrice via ".lafonction("apply")." dans les codes $R suivants :" ;
01515 finp() ;
01516
01517 pre_fichier("somcol3.txt","cadre") ;
01518
01519
01520 finblockquote() ;
01521
01522 #######################################################################################################################
01523
01524 $tdmCRLM5->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Tests des paramètres
01525
01526 ## -------------------------------------------------------------------------------------------
01527
01528 blockquote() ;
01529
01530 p("texte") ;
01531 echo " On peut tester si un paramètre est présent (ou plutôt absent) avec " ;
01532 echo b("missing(paramètre)").". La liste des paramètres est fournie par ".b("formals(fonction)")." mais on " ;
01533 echo " peut aussi utiliser ".b("args(fonction)")." pour connaitre l'entête de la fonction ; le texte de la fonction est donné par " ;
01534 echo " ".b("body(fonction)")."." ;
01535 echo " Voici quelques exemples qui montrent que $R est un langage assez ".b("ouvert")." puisqu'on peut consulter le code source du langage :" ;
01536 finp() ;
01537
01538 pre_fichier("param1.txt","cadre") ;
01539
01540 p("texte") ;
01541 echo "Il est classique de tester le type (la classe des paramètres) avec une fonction ".b("is.").vert("*") ;
01542 echo " et de quitter le programme avec ".b("stop")." ou ".b("stopifnot").". " ;
01543 echo " Voici là encore quelques exemples issus du propre code de $R :" ;
01544 finp() ;
01545
01546 pre_fichier("param2.txt","cadre") ;
01547
01548 finblockquote() ;
01549
01550 #######################################################################################################################
01551
01552 $tdmCRLM5->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # L'ellipse notée ...
01553
01554 ## -------------------------------------------------------------------------------------------
01555
01556 blockquote() ;
01557
01558 p("texte") ;
01559 echo "Comme le montrent les exemples précédents, un argument possible pour une fonction est l'ellipse, qui se note " ;
01560 echo rouge("...")." (trois points qui se suivent) et dont l'aide est " ;
01561 echo hrrr("dotsMethods","methods","ici").". " ;
01562 echo " Cette notation, qui se révèle très pratique à l'usage, permet de ne pas spécifier tous les paramètres à utiliser " ;
01563 echo " et de laisser le soin à $R de les transmettre. " ;
01564 echo " L'ellipse sert beaucoup lorsqu'on écrit une fonction de tracé graphique et pour implémenter des fonctions génériques. " ;
01565 echo " Les paramètres qu'on définit sont les plus " ;
01566 echo " usuels et l'ellipse permet de passer les moins fréquents. " ;
01567 finp() ;
01568
01569 p("texte") ;
01570 echo "Imaginons par exemple que l'on veuille interfacer la fonction ".hrrr("boxplot","graphics") ;
01571 echo " avec un titre et une unité obligatoires. Voici la trame d'une " ;
01572 echo " telle fonction :" ;
01573 finp() ;
01574
01575 pre_fichier("boxplot1.r","cadre") ;
01576
01577 p("texte") ;
01578 echo "Il est clair qu'avec une telle fonction on ne peut pas modifier les bornes ".b("xlim")." et ".b("ylim") ;
01579 echo " du tracé, par exemple. Au lieu de les rajouter comme arguments, le mieux est d'ajouter l'ellipse. " ;
01580 echo " Dès lors, l'utilisateur a accès à toutes les options de boxplot :" ;
01581 finp() ;
01582
01583 pre_fichier("boxplot2.r","cadre") ;
01584
01585 finblockquote() ;
01586
01587 #######################################################################################################################
01588
01589 $tdmCRLM5->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Quelques exemples de fonctions
01590
01591 ## -------------------------------------------------------------------------------------------
01592
01593 blockquote() ;
01594
01595 p("texte") ;
01596 echo "Afin de vous entrainer à bien \"parler fonction en $R\", voici quatres exemples qui mettent en \n" ;
01597 echo "pratique tout ce que nous venons de décrire. Nous montrerons au passage comment \"progresser\" \n" ;
01598 echo "dans l'écriture d'une fonction. \n" ;
01599 finp() ;
01600
01601 h2("$numRub.1 La fonction moyenne()") ;
01602
01603 p("texte") ;
01604 echo "Pour implémenter une fonction nommée ".b("moyenne()")." -- aussi bizarre que cela puisse \n" ;
01605 echo "paraitre à une ou un néophyte, cette définition est plus rapide que la \"vraie\" fonction ".hrrr("mean")." \n" ;
01606 echo "de $R pour des petits vecteurs numériques -- le code minimal est le suivant : \n" ;
01607 finp() ;
01608
01609 pre_fichier("moyenne1.r","cadre") ;
01610
01611 p("texte") ;
01612 echo "Cet exemple de définition est suffisant dans l'environnement de $R, en mode interactif, si \n" ;
01613 echo "on est pressé de tester la fonction. \n" ;
01614 finp() ;
01615
01616 p("texte") ;
01617 echo "Toutefois, il vaut mieux mettre un commentaire pour \n" ;
01618 echo "détailler ce que fait la fonction et utiliser explicitement le mot ".b("return()")." pour \n" ;
01619 echo "indiquer ce qui est renvoyé : \n" ;
01620 finp() ;
01621
01622 pre_fichier("moyenne2.r","cadre") ;
01623
01624 p("texte") ;
01625 echo "Après réflexion, vous pourrez vous rendre compte que l'argument de ".b("moyenne()")." doit \n" ;
01626 echo "être numérique, car sinon la fonction ".hrrr("sum")." échoue. De même, s'il y a des ".b("NA")." \n" ;
01627 echo "dans les valeurs, la fonction ".hrrr("sum")." échoue aussi. D'où une version 3, plus stable et plus \n" ;
01628 echo "complète pour la moyenne, avec au passage une séparation du calcul du renvoi de la valeur calculée : \n" ;
01629 finp() ;
01630
01631 pre_fichier("moyenne3.r","cadre") ;
01632
01633 p("texte") ;
01634 echo "Vous aurez compris, au vu de cette progression, qu'écrire une fonction ne se fait pas forcément du \n" ;
01635 echo "premier jet. Le nom et le choix de la valeur par défaut du paramètre ".b("oteNA")." pour supprimer \n" ;
01636 echo "les valeurs ".b("NA")." devrait aussi être détaillé. Nous avons ici pris le parti de reproduire \n" ;
01637 echo "la valeur par défaut de la fonction ".hrrr("mean").", mais sans utiliser le même nom de paramètre \n" ;
01638 echo "que $R utilise, à savoir ".b("na.omit").", ce \n" ;
01639 echo "qui est un petit peu maladroit (volontairement). \n" ;
01640 finp() ;
01641
01642 h2("$numRub.2 La fonction médiane()") ;
01643
01644 p("texte") ;
01645 echo "Forts de notre expérience avec la fonction ".b("moyenne()")." précédente, nous pourrions être tentés d'écrire de \n" ;
01646 echo "suite un \"beau\" code \"stable et complet\" pour la fonction ".b("mediane()")." comme ceci : \n" ;
01647 finp() ;
01648
01649 pre_fichier("mediane1.r","cadre") ;
01650
01651 p("texte") ;
01652 echo "C'est sans doute une \"belle\" fonction, mais elle est incomplète, \n" ;
01653 echo "parce que la médiane peut se calculer sur des vecteurs de caractères \n" ;
01654 echo "avec un nombre pair de termes. \n" ;
01655 finp() ;
01656
01657 p("texte") ;
01658 echo "On remarquera que nous avons désormais écrit pour le paramètre ".b("na.rm")." au lieu de ".b("oteNA")." comme pour la fonction \n" ;
01659 echo b("moyenne()")." précédente. C'est sans doute mieux, car cela aide à \n" ;
01660 echo "se rappeler comment on écrit cela dans les autres fonctions standards de $R. \n" ;
01661 finp() ;
01662
01663 p("texte") ;
01664 echo "Programmer, c'est aussi évoluer, changer d'avis, à condition de le dire et de rester \n" ;
01665 echo "cohérent avec les autres fonctions de $R ! \n" ;
01666 finp() ;
01667
01668 h2("$numRub.3 La fonction decritColonne()") ;
01669
01670 p("texte") ;
01671 echo "$R fournit de nombreuses fonctions pour décrire une variable quantitative comme le poids, ou la taille. \n" ;
01672 echo "Il y a les fonctions élémentaires comme ".hrrr("mean").", ".hrrr("sd","stats")." et des fonctions plus complètes comme \n" ;
01673 echo hrrr("summary")." ou ".hrrr("fivenum","stats").". \n" ;
01674 finp() ;
01675
01676 p("texte") ;
01677 echo "Toutes ces fonctions ont un gros défaut : elles n'indiquent pas l'unité. \n" ;
01678 echo "Ainsi voir une taille de 5,6 pour des adultes peut apparaitre comme une erreur pour un français. \n" ;
01679 echo "Avec l'indication 5,6 pieds, ce serait mieux car vu qu'un pied fait 30,47 centimètres \n" ;
01680 echo "la valeur 5,6 pieds correspond approximativement à 170,6 cm, ce qui montre bien qu'il ne s'agit pas d'une erreur. \n" ;
01681 finp() ;
01682
01683 p("texte") ;
01684 echo "Nous nous proposons ici d'ajouter une unité à la \n" ;
01685 echo "description statistique classique et de considérer ce paramètre comme obligatoire. \n" ;
01686 finp() ;
01687
01688 p("texte") ;
01689 echo "Nous allons nous focaliser sur les descripteurs de ".b("tendance centrale")." que sont la moyenne et la médiane, et sur les \n" ;
01690 echo em("valeurs de controle")." -- il faudrait bien sûr ajouter des indicateurs de ".em("dispersion")." absolue et relative, \n" ;
01691 echo "comme l'écart-type, la distance interquartile, le coefficient de variation... pour être plus complet -- \n" ;
01692 echo "que sont le minimum et le maximum afin de rester dans des calculs simples et compréhensibles. \n" ;
01693 finp() ;
01694
01695 p("texte") ;
01696 echo "Nous ne fournissons pas non plus de code pour représenter graphiquement les données et ces indicateurs mais ce serait \n" ;
01697 echo "indispensable s'il s'agissait d'écrire une \"vraie\" fonction statistique de description d'une variable quantitative dont \n" ;
01698 echo "on connait l'unité. \n" ;
01699 finp() ;
01700
01701 p("texte") ;
01702 echo "Comme programmer, c'est se rappeler des programmes déjà écrits, nous refuserons bien évidemment d'appliquer la fonction \n" ;
01703 echo "à des données qui ne sont pas numériques. \n" ;
01704 finp() ;
01705
01706 p("texte") ;
01707 echo "Voici un code possible pour cette \n" ;
01708 echo "fonction : \n" ;
01709 finp() ;
01710
01711 pre_fichier("decrit01.r","cadre") ;
01712
01713 p("texte") ;
01714 echo "Le choix du nom des variables et des fonctions est important. Ici, ".b("decritColonne()")." est sans doute maladroit \n" ;
01715 echo "et ".b("decritQuantitative()")." aurait été plus approprié. Toutefois, il est possible que l'utilisation principale \n" ;
01716 echo "de cette fonction soit d'être appelée par une fonction plus générale, nommée par exemple \n" ;
01717 echo b("decritColonnes()")." -- donc avec un ".b("s")." en plus à la fin -- et là, le nom de la fonction se justifie \n" ;
01718 echo "tout à fait. \n" ;
01719 finp() ;
01720
01721 p("texte") ;
01722 echo "Voici un exemple d'utilisation : \n" ;
01723 finp() ;
01724
01725 pre_fichier("decrit01.txt","cadre") ;
01726
01727 h2("$numRub.4 La fonction plotCouleur()") ;
01728
01729 p("texte") ;
01730 echo "Il est très courant d'avoir à coloriser des points dans un tracé, par exemple pour repérer les hommes et les femmes \n" ;
01731 echo "dans une étude épidémiologique. Nous présentons ici une fonction dont la syntaxe est \n" ;
01732 echo b("plotCouleur(x,y,facteur,couleurs)").". Ainsi, pour tracer le poids en fonction de l'age avec \n" ;
01733 echo "la couleur bleue pour les garçons et rouge pour les filles, on réaliserait l'appel \n" ;
01734 echo b("plotCouleur(age,poids,sexe,c(\"blue\",\"red\"))")." ou, si astucieusement on dispose d'une liste de \n" ;
01735 echo "couleurs par défaut, l'appel peut se résumer à \n" ;
01736 echo b("plotCouleur(age,poids,sexe)").". Voici la fonction : \n" ;
01737 finp() ;
01738
01739 pre_fichier("plotcoul01.r","cadre") ;
01740
01741 p("texte") ;
01742 echo "Vous aurez remarqué, bien sûr, que nous avons utilisé l'ellipse. \n" ;
01743 echo "Attention toutefois : $R n'autorise pas de spécifier plusieurs fois le même paramètre. Ainsi, puisque nous \n" ;
01744 echo "utilisons déjà le paramètre ".b("pch").", l'appel suivant est incorrect \n" ;
01745 echo " \n" ;
01746 finp() ;
01747
01748 pre_fichier("plotcoul01.txt","cadre") ;
01749
01750 finblockquote() ;
01751
01752 #######################################################################################################################
01753
01754 $tdmCRLM5->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Spécificités du langage $R
01755
01756 ## -------------------------------------------------------------------------------------------
01757
01758 blockquote() ;
01759
01760 p("texte") ;
01761 echo "$R est très différent des autres langages par rapport aux fonctions :" ;
01762 finp() ;
01763
01764 ul() ;
01765
01766 debutli() ;
01767 p("texte") ;
01768 echo " les fonctions sont ".rouge("nativement vectorielles")." si les calculs utilisés sont vectoriels, ou si on y fait appel à " ;
01769 echo " d'autres fonctions vectorielles. " ;
01770 finp() ;
01771 finli() ;
01772
01773 debutli() ;
01774 p("texte") ;
01775 echo " les fonctions sont ".rouge("des objets comme les autres")." et peuvent être passés en paramètres :" ;
01776 finp() ;
01777 pre_fichier("ifelse-fonctions.r","cadre") ;
01778 finli() ;
01779
01780 debutli() ;
01781 p("texte") ;
01782 echo rouge(" les paramètres sont nommés")." et ils peuvent avoir des valeurs par défaut, ce qui fournit une " ;
01783 echo " très grande souplesse d'utilisation (et un casse-tête pour les mémoriser). " ;
01784 finp() ;
01785 finli() ;
01786
01787 finul() ;
01788
01789 p("texte") ;
01790 echo "Par contre ce nommage n'est pas normalisé et ne peut pas l'être, compte tenu des structures de données de $R :" ;
01791 finp() ;
01792
01793 pre_fichier("fns.r","cadre") ;
01794
01795 finblockquote() ;
01796
01797 #######################################################################################################################
01798 #
01799 # progic6
01800 #
01801 #######################################################################################################################
01802
01803 $numcours = 6 ; partie($numcours) ; pvide() ;
01804 $rubrique = 0 ;
01805 $rubriques6 = array() ;
01806 $rubrique++ ; $rubriques6[$rubrique] = "Via les fonctions de base déjà existantes" ;
01807 $rubrique++ ; $rubriques6[$rubrique] = "Via les packages" ;
01808 $rubrique++ ; $rubriques6[$rubrique] = "Eviter de programmer des boucles avec la famille ".rouge("*apply*") ;
01809 $rubrique++ ; $rubriques6[$rubrique] = "Apprendre les actions courantes en $R" ;
01810 $rubrique++ ; $rubriques6[$rubrique] = "Comment survivre à $R ?" ;
01811
01812 $tdmCRLM6 = new tdm($rubriques6) ;
01813 $tdmCRLM6->titre() ;
01814 $tdmCRLM6->menu("oui","oui","nou","p$numcours") ;
01815
01816 $numRub = 0 ;
01817
01818 #######################################################################################################################
01819
01820 $tdmCRLM6->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Via les fonctions de base déjà existantes
01821
01822 ## -------------------------------------------------------------------------------------------
01823
01824 blockquote() ;
01825
01826 p("texte") ;
01827 echo "Lorsqu'on débute en programmation, il est bon d'apprendre à savoir tout faire, tout calculer. Par exemple " ;
01828 echo " pour les statistiques usuelles, il faut savoir effectuer un calcul de moyenne, de médiane, d'écart-type. " ;
01829 echo " Il faut avoir écrit au moins une fois dans sa vie la recherche du minimum, du maximum dans un vecteur, avec " ;
01830 echo " leur nombre d'ocurrences et leurs positions pour commencer à savoir programmer. " ;
01831 finp() ;
01832
01833 p("texte") ;
01834 echo "Savoir programmer, c'est ensuite savoir utiliser les programmes des autres, donc ne pas réinventer la roue, l'eau tiède, etc." ;
01835 echo " $R dispose de nombreuses fonctions de base en standard, via les packages " ;
01836 echo hrrp("base").", ".hrrp("stats").", ".hrrp("graphics")." et ".hrrp("utils")." : " ;
01837 finp() ;
01838
01839 blockquote() ;
01840 $nbo = array() ;
01841 $nbo["base"] = 1167 ;
01842 $nbo["stats"] = 493 ;
01843 $nbo["graphics"] = 87 ;
01844 $nbo["utils"] = 198 ;
01845 table(1,10,"collapse") ;
01846 entetesTableau("package nbObjets liste","jaune_pastel") ;
01847 foreach (preg_split("/\s+/","base stats graphics utils") as $nom) {
01848 tr() ;
01849 td() ; echo hrrp($nom) ; fintd() ;
01850 td("R") ; echo $nbo[$nom]." " ; fintd() ;
01851 td() ; echo " ".href("lls_".$nom.".sor") ; fintd() ;
01852 fintr() ;
01853 } ; # fin pou chaque
01854 fintable() ;
01855 finblockquote() ;
01856
01857
01858 p("texte") ;
01859 echo "Apprendre à programmer en $R consiste donc à passer beaucoup de temps, au moins au début," ;
01860 echo " pour savoir ce que $R sait déjà faire -- et il en fait déjà beaucoup. Car tous les traitements " ;
01861 echo " de données usuels (transformations, recodages, discrétisation, fusion...) ont déjà été passés en revue, " ;
01862 echo " analysés, programmés, parfois de façon très sophistiquée." ;
01863 echo " On pourra consulter les fonctions " ;
01864 echo hrrr("transform")." et ".hrrr("stack","utils")." pour s'en rendre compte." ;
01865 finp() ;
01866
01867 p("texte") ;
01868 echo "De même, puisque $R est un logiciel pour les calculs statistiques, tous les calculs usuels et même " ;
01869 echo " les calculs récents en statistique, bioinformatique, etc. sont déjà implémentés en $R. " ;
01870 echo " Une ".b("grande conclusion")." est qu'il faut passer du temps avant de «".em("maitriser la bête")."». " ;
01871 echo " L'expérience prouve qu'on y gagne en vitesse de développement et en compréhension du fonctionnement du langage $R." ;
01872 finp() ;
01873
01874 p("texte") ;
01875 echo "Soyons clairs : sauf si vous inventez une nouvelle méthode de calcul en statistiques, " ;
01876 echo b("vous n'avez pas à programmer le moindre calcul statistique en $R").". " ;
01877 echo " Vous avez à lire les données, appeler les fonctions de $R qui calculent, vous avez à mettre en forme les résultats, mais " ;
01878 echo " vous n'avez pas à programmer le moindre calcul statistique en $R (redite volontaire). " ;
01879 finp() ;
01880
01881 finblockquote() ;
01882
01883 #######################################################################################################################
01884
01885 $tdmCRLM6->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Via les packages
01886
01887 ## -------------------------------------------------------------------------------------------
01888
01889 blockquote() ;
01890
01891 p("texte") ;
01892 echo "Plus encore que les deux mille et quelques fonctions des quatre packages de la section précédente, c'est ";
01893 echo " la ".em("foultitude")." des packages spécialisés qui fait la richesse de $R et qui le rend incomparable pour les " ;
01894 echo " calculs et les graphiques statistiques. " ;
01895 finp() ;
01896
01897 p("texte") ;
01898 echo "Même si d'autres langages peuvent être considérés comme \"plus beaux\", \"plus propres\", \"plus efficaces\", disons comme " ;
01899 echo href("../../../tuteurs/tutruby.php","Ruby").", " ;
01900 echo href("../../../tuteurs/tutpython.php","Python").", " ;
01901 echo href("http://fr.wikipedia.org/wiki/Java_%28langage%29","Java").", " ;
01902 echo href("http://fr.wikipedia.org/wiki/C_%28langage%29","C")."..., " ;
01903 echo " aucun autre langage de programmation n'est aussi complet dès qu'il s'agit de graphiques et de calculs statistiques. La preuve :" ;
01904 echo " ces langages ont préféré développer des interfaces de dialogue avec $R plutôt que de réimplémenter les mêmes calculs ";
01905 echo " et graphiques. C'est ainsi qu'on trouve " ;
01906 echo href("http://rpy.sourceforge.net/","rpy").", " ;
01907 echo href("https://sites.google.com/a/ddahl.org/rinruby-users/Home","rinruby").", " ;
01908 echo href("http://cran.r-project.org/web/packages/rJava/index.html","rJava").", " ;
01909 echo href("http://cran.r-project.org/web/packages/Rcpp/index.html","Rcpp")."..." ;
01910 finp() ;
01911
01912 p("texte") ;
01913 echo "Il suffit de consulter chaque jour la " ;
01914 echo href("http://cran.r-project.org/","liste des packages ajoutés quotidiennement")." pour constater que le nombre de packages grandit vraiment ";
01915 echo " très vite et qu'aucun autre langage ne croit aussi vite... " ;
01916 finp() ;
01917
01918 p("texte") ;
01919 echo "Même dans certains domaines où on pourrait ne pas l'y attendre, $R se révéle performant grâce à son aspect " ;
01920 echo rouge("vectoriel").". Le package ".hrrp("XML")." et le livre associé en sont un très bon exemple." ;
01921 finp() ;
01922
01923 p() ;
01924 nbsp(10) ;
01925 $img = "Rxml.jpg" ;
01926 echo href("http://www.springer.com/gp/book/9781461478997",img($img,"",150)) ;
01927 finp() ;
01928
01929 p("texte") ;
01930 echo "Au passage, l'un des points forts de $R est la mise en forme ou la restructuration des données. " ;
01931 echo " On pourra consulter les packages " ;
01932 echo hrrp("plyr")." et ".hrrp("reshape2")." pour s'en rendre compte" ;
01933 finp() ;
01934
01935 finblockquote() ;
01936
01937 #######################################################################################################################
01938
01939 $tdmCRLM6->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Eviter de programmer des boucles avec la famille *apply*
01940
01941 ## -------------------------------------------------------------------------------------------
01942
01943 blockquote() ;
01944
01945 p("texte") ;
01946 echo "Programmer des calculs, des affichages revient souvent à ".b("appliquer")." un même traitement " ;
01947 echo " à de nombreux \"objets\". Dans la mesure où $R distingue les vecteurs, les matrices et les listes " ;
01948 echo " (dont les data frames), il n'est pas étonnant que ce mot ".b("appliquer")." se décline en plusieurs versions " ;
01949 echo " suivant les structures de données :" ;
01950 finp() ;
01951
01952 pre_fichier("apply.txt","cadre") ;
01953
01954 p("texte") ;
01955 echo "La fonction " ;
01956 echo hrrr("apply")." utilise des objets \"matrice\". Sa syntaxe de base utilise les paramètres " ;
01957 echo b("X")." qui est la matrice ou un objet assimilable à une matrice, " ;
01958 echo b("FUN")." la fonction à appliquer, qu'elle soit nommée ou anonyme et " ;
01959 echo b("MARGIN")." pour préciser si on applique la fonction dans le sens des lignes (MARGIN=1) ou des " ;
01960 echo " colonnes (MARGIN=2)." ;
01961 finp() ;
01962
01963 p("texte") ;
01964 echo "La fonction " ;
01965 echo hrrr("lapply")." utilise une liste nommée " ;
01966 echo b("X")." et lui applique la fonction " ;
01967 echo b("FUN")." élément par élément." ;
01968 echo " L'objet renvoyé est une liste. " ;
01969 finp() ;
01970
01971 p("texte") ;
01972 echo "La fonction " ;
01973 echo hrrr("lapply","","sapply()")." exécute ".b("lapply()")." et en simplifie la sortie ";
01974 echo " pour renvoyer un vecteur ou une matrice. ".b("sapply")." utilise donc les mêmes paramètres que ".b("lapply").". " ;
01975 finp() ;
01976
01977 p("texte") ;
01978 echo "La fonction " ;
01979 echo hrrr("rapply")." exécute récursivement son paramètre ".b("f")." sur son autre paramètre ".b("object").", " ;
01980 echo " ce que ne savent pas faire les fonctions précédentes." ;
01981 finp() ;
01982
01983 p("texte") ;
01984 echo "La fonction " ;
01985 echo hrrr("tapply")." permet de découper le paramètre ".b("X")." selon le paramètre ".b("INDEX")." avant d'appliquer " ;
01986 echo " son paramètre ".b("FUN")." à chaque découpage obtenu. C'est donc en quelque sorte l'enchainement de " ;
01987 echo hrrr("split")." et " ;
01988 echo hrrr("lapply").". " ;
01989 finp() ;
01990
01991 p("texte") ;
01992 echo "La fonction " ;
01993 echo hrrr("lapply","","vapply")." permet de préciser à ".b("sapply")." quel type de données on obtiendra en sortie." ;
01994 finp() ;
01995
01996
01997 p("texte") ;
01998 echo "La fonction " ;
01999 echo hrrr("mapply")." travaille en \"multivarié\"." ;
02000 finp() ;
02001
02002
02003 p("texte") ;
02004 echo "Notre " ;
02005 echo href("../Programmation_avancee/progr.php?n=1&m=e","cours 1") ;
02006 echo " de " ;
02007 echo href("../Programmation_avancee/progr.php","programmation $R avancée").", " ;
02008 echo " exercice 5 et " ;
02009 echo href("../Programmation_avancee/progr.php?n=1&m=e","sa solution") ;
02010 echo" montre par l'exemple comment utiliser ces fonctions." ;
02011 finp() ;
02012
02013 finblockquote() ;
02014
02015 #######################################################################################################################
02016
02017 $tdmCRLM6->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Apprendre les actions courantes en R
02018
02019 ## -------------------------------------------------------------------------------------------
02020
02021 blockquote() ;
02022
02023 p("texte") ;
02024 echo "S'il n'est pas possible de tout apprendre en $R, il est facile de prévoir un planning et un ordre " ;
02025 echo " pour apprendre les actions courantes en $R :" ;
02026 finp() ;
02027
02028 ol() ;
02029
02030 debutli() ; p("texte") ;
02031 echo "On commence presque toujours par lire des données. Donc tout ce qui se nomme " ;
02032 echo vert("read.").rouge("*")." est bon à prendre et à apprendre, dont la lecture des fichiers Excel, des fichiers PDF " ;
02033 echo " ou autres fichiers XML ou Fasta..." ;
02034 echo "Si on ne lit pas des fichiers, c'est qu'on lit des bases de données ou qu'on simule des données. Là encore les " ;
02035 echo "packages de $R sont faciles à trouver qui remplissent ces tâches, " ;
02036 echo " par exemple avec ".href("http://finzi.psych.upenn.edu/nmz.html","R Site Search")."..." ;
02037 finp() ;
02038
02039 pre_fichier("read.txt","cadre") ;
02040
02041 finli() ;
02042
02043 debutli() ; p("texte") ;
02044 echo "Avec des données, on effectue des calculs, on produit des graphiques. Les " ;
02045 echo href("http://cran.r-project.org/web/views/",em("task views")) ;
02046 echo " du ".href("http://cran.r-project.org/","CRAN") ;
02047 echo " permettent de s'y retrouver. " ;
02048 echo " Pour celles et ceux qui travaillent dans le domaine de la bioinformatique, on rajoutera les pages ";
02049 echo href("http://www.bioconductor.org/packages/release/BiocViews.html#___Software","Explore packages") ;
02050 echo " et " ;
02051 echo href("http://www.bioconductor.org/help/","help") ;
02052 echo " de " ;
02053 echo href("http://www.bioconductor.org/","bioconductor") ;
02054 echo "." ;
02055 finp() ;
02056
02057 p("texte") ;
02058 echo "Une fois maitrisés les calculs élémentaires, vous pouvez aborder les modélisations classiques qui reposent sur le modèle linéaire (soit " ;
02059 echo " la fonction ".hrrr("lm","stats").") et " ;
02060 echo " sa généralisation (soit la fonction ".hrrr("glm","stats").") soit basculer vers le non linéaire, par exemple avec " ;
02061 echo lafonction("nlm","stats")." ou des fonctions comme " ;
02062 echo hrrr("loess","stats")." ou " ;
02063 echo hrrr("lowess","stats").". " ;
02064 finp() ;
02065
02066 pre_fichier("lm.txt","cadre") ;
02067
02068 p("texte") ;
02069 echo "Pour les tests, $R implémente \"tout ce qui bouge\" et ".em("plus si affinités,") ;
02070 echo " ce qui se nomme plus ou moins ".b("*.test()")." ou ".hrrr("anova","stats")." :" ;
02071 finp() ;
02072
02073 pre_fichier("test.txt","cadre") ;
02074
02075 finli() ;
02076
02077 debutli() ; p("texte") ;
02078 echo "Il faut ensuite mettre en forme les calculs, produire des rapports, intégrer les graphiques, exporter vers " ;
02079 echo " des formats classiques comme les précédents (Excel, PDF, base de données, XML...). Donc il faut approfondir ";
02080 echo " tout ce qui se nomme ".vert("write.").rouge("*")." et tout ce qui se trouve dans le package ".hrrp("gdata").". " ;
02081 finp() ;
02082
02083 pre_fichier("write.txt","cadre") ;
02084
02085 finli() ;
02086
02087 finol() ;
02088
02089 finblockquote() ;
02090
02091 #######################################################################################################################
02092
02093 $tdmCRLM6->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Comment survivre à R
02094
02095 ## -------------------------------------------------------------------------------------------
02096
02097 blockquote() ;
02098
02099 p("texte") ;
02100 echo "Malheureusement, la richesse de $R en fait aussi son plus gros défaut. " ;
02101 echo " Il faut apprendre une grosse centaine de fonctions (et leurs paramètres) " ;
02102 echo " avant de commencer à écrire des programmes concis, ".b("il faut désapprendre les boucles ") ;
02103 echo " dans un certain nombre de cas avant de bien profiter des aspects ".rouge("vectoriels")." de $R, " ;
02104 echo " il faut être à l'aise avec les méthodes statistiques pour s'y retrouver facilement dans les " ;
02105 echo " packages et les options implémentées, bref ce n'est pas une mince affaire que de bien programmer en $R." ;
02106 finp() ;
02107
02108 p("texte") ;
02109 echo "Heureusement, avec «du coeur à l'ouvrage» et de nombreuses heures d'entrainement, on y arrive ";
02110 echo "toujours !" ;
02111 finp() ;
02112
02113 finblockquote() ;
02114
02115 #######################################################################################################################
02116 #
02117 # progic7
02118 #
02119 #######################################################################################################################
02120
02121 $numcours = 7 ; partie($numcours) ; pvide() ;
02122 $rubrique = 0 ;
02123 $rubriques7 = array() ;
02124 $rubrique++ ; $rubriques7[$rubrique] = "Structure de données classiques des autres langages" ;
02125 $rubrique++ ; $rubriques7[$rubrique] = "Problèmes demandant des compétences techniques en algorithmique" ;
02126 $rubrique++ ; $rubriques7[$rubrique] = "Problèmes de grande taille (big data)" ;
02127 $rubrique++ ; $rubriques7[$rubrique] = "Problèmes de grande ampleur (big computing)" ;
02128 $rubrique++ ; $rubriques7[$rubrique] = "La récursivité" ;
02129
02130 $tdmCRLM7 = new tdm($rubriques7) ;
02131 $tdmCRLM7->titre() ;
02132 $tdmCRLM7->menu("oui","oui","nou","p$numcours") ;
02133
02134 $numRub = 0 ;
02135
02136 #######################################################################################################################
02137
02138 $tdmCRLM7->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Structure de données classiques des autres langages
02139
02140 ## -------------------------------------------------------------------------------------------
02141
02142 blockquote() ;
02143
02144
02145 p("texte") ;
02146 echo "Lorsqu'on suit des cours de programmation, on apprend des techniques classiques et des modèles de " ;
02147 echo " résolution de problèmes, nommés en anglais " ;
02148 echo href("http://fr.wikipedia.org/wiki/Patron_de_conception","Design Patterns").". ";
02149 echo " On apprend aussi à utiliser des " ;
02150 echo href("http://fr.wikipedia.org/wiki/Structure_de_donn%C3%A9es","structures de données adaptées").", " ;
02151 echo " comme les piles, les queues, les files, les graphes (dont les arbres), les listes chainées, les tableaux associatifs..." ;
02152 echo " Il faut donc de nombreuses heures de cours et de pratique avant de maitriser la programmation. Les cours présentés " ;
02153 echo " ici ne peuvent prétendre se substituer à ces enseignements traditionnels, tout au plus sensibiliser à l'importance de " ;
02154 echo " ces concepts via quelques exemples choisis." ;
02155 finp() ;
02156
02157 p("texte") ;
02158 echo "On trouvera donc dans les exercices de ce cours des graphes, des arbres et des tableaux associatifs à titre " ;
02159 echo " d'illustration." ;
02160 finp() ;
02161
02162 p("texte") ;
02163 echo "Il faut noter aussi que l'utilisation de $R est souvent liée à des calculs statistiques, discipline qui a ses propres " ;
02164 echo " structures comme les séries chronologiques, les variables ordinales, les matrices de distances, les arbres de classification hiérarchique... " ;
02165 echo " et ses propres méthodes comme le modèle linéaire, " ;
02166 echo " les intervalles de confiance... " ;
02167 finp() ;
02168
02169 finblockquote() ;
02170
02171 #######################################################################################################################
02172
02173 $tdmCRLM7->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Problèmes demandant des compétences techniques en algorithmique
02174
02175 ## -------------------------------------------------------------------------------------------
02176
02177 blockquote() ;
02178
02179 # plus grande sous-chaine répétée via un tableau des suffixes
02180
02181 p("texte") ;
02182 echo "Voici un problème qui a l'air presque anodin : quelle est la plus grande sous-chaine de caractères répétée dans une chaine de caractères ?" ;
02183 echo " Attention : il ne s'agit pas de trouver la lettre la plus souvent utilisée, mais une sous-chaine. Pour un texte \"littéraire\", avec des " ;
02184 echo " avec des \"vrais\" mots, c'est facile à faire et rapide. Voir par exemple le site " ;
02185 echo href("http://forge.info.univ-angers.fr/~gh/Wanalexies/f_dicos.php","analexies").". ";
02186 $adn = "../../../Abdc/Data/putida_gb_1.fasta.zip" ;
02187 echo "Mais pour une séquence d'ADN comme ".href($adn,"celle de Pseudomonas putida GB-1")." (soit un peu plus de 6 millions de lettres), " ;
02188 echo " comment faire ?";
02189 # plus grande sous-chaine répétée via un tableau des suffixes
02190 echo "" ;
02191 finp() ;
02192
02193 p("texte") ;
02194 echo "C'est grâce à l'étude de structures de données adaptées comme celle de " ;
02195 $tds = "http://en.wikipedia.org/wiki/Suffix_array" ;
02196 echo href($tds,"tableau des suffixes")." que le problème se résoud de façon « assez rapide » (quelques dizaines de secondes " ;
02197 echo " sur un ordinateur récent un peu puissant, pour ".b("Pseudomonas putida GB-1")."). " ;
02198 echo " Il est clair qu'une structure comme celle-là ne s'invente pas en pensant dix minutes au problème. " ;
02199 echo " C'est pourquoi il y a un moment où savoir programmer dans un langage ne suffit plus : il faut aussi savoir " ;
02200 echo " inventer des algorithmes, connaitre les algorithmes classiques et les structures de données associées. " ;
02201 echo " Voici deux références pour progresser dans ce domaine :" ;
02202 finp() ;
02203
02204 $r1 = "http://pauillac.inria.fr/~maranget/X/421/poly/poly.pdf" ;
02205 $r2 = "http://algs4.cs.princeton.edu/home/" ;
02206 $r3 = "poly_technique.pdf" ;
02207
02208 ul() ;
02209
02210 debutli() ;
02211 p() ;
02212 echo href($r1,"Algorithmique et Programmation JAVA")." : un polycopié en français de polytechnique " ;
02213 echo "(".href($r3,"version locale").")" ;
02214 echo " ;" ;
02215 finp() ;
02216 finli() ;
02217
02218 debutli() ;
02219 p() ;
02220 echo href($r2,"Algorithms")." : une grande référence anglaise sur les algorithmes." ;
02221 finp() ;
02222 finli() ;
02223
02224 finul() ;
02225
02226 finblockquote() ;
02227
02228 #######################################################################################################################
02229
02230 $tdmCRLM7->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Problèmes de grande taille
02231
02232 ## -------------------------------------------------------------------------------------------
02233
02234 blockquote() ;
02235
02236 p("texte") ;
02237 echo "Lorsque les données sont très importantes (disons quelques dizaines de giga octets ou tera octets), " ;
02238 echo " ce qui est souvent le cas en bioinformatique, en [méta]génomique, de nouvelles difficultés surgissent :" ;
02239 echo " il n'est plus possible de charger les données en mémoire, ou seulement partiellement, les calculs ne peuvent plus " ;
02240 echo " s'exécuter sur un seul ordinateur et il faut recourir à un ".b("cluster")." ou à une ".b("grid")." de calculateurs..." ;
02241 finp() ;
02242
02243 p("texte") ;
02244 echo "La programmation en \"grande dimension\" (autre nom du ".b("big data").") nécessite des approches algorithmiques différentes de " ;
02245 echo " la programmation classique. Ce sujet est beaucoup trop technique pour pouvoir être abordé dans un cours comme celui-ci" ;
02246 echo " qui est une ".em("petite")." introduction à la programmation classique, mais il est bon de savoir qu'il existe des solutions, " ;
02247 echo " par exemple ".href("http://revolutionanalytics.com/","Revolution R").", qu'on y parle " ;
02248 echo href("https://fr.wikipedia.org/wiki/Hadoop","Hadoop") ;
02249 echo " et autres " ;
02250 echo href("https://fr.wikipedia.org/wiki/MapReduce","map/reduce") ;
02251 echo" ou " ;
02252 echo href("http://cryto.net/~joepie91/blog/2015/05/04/functional-programming-in-javascript-map-filter-reduce/","map/filter/reduce") ;
02253 echo ", de la ".href("https://fr.wikipedia.org/wiki/Programmation_fonctionnelle","programmation fonctionnelle")."." ;
02254 finp() ;
02255
02256 finblockquote() ;
02257
02258 #######################################################################################################################
02259
02260 $tdmCRLM7->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Problèmes de grande ampleur
02261
02262 ## -------------------------------------------------------------------------------------------
02263
02264 blockquote() ;
02265
02266 p("texte") ;
02267 echo "Contrairement à un problème de grande taille, un problème de grande ampleur peut avoir des données de taille " ;
02268 echo "«raisonnable» mais leur traitement nécessite des capacités gigantesques. Un exemple classique est la " ;
02269 echo " détermination (calcul ?) de ".b("sous-").rouge("séquences").b(" répétées")." à ne pas confondre avec le " ;
02270 echo " calcul de ".b("sous-").vert("chaines").b(" répétées")." (qui, lui, se traite «assez facilement»). " ;
02271 echo " Dans les phrases ".b("un bateau qui va sur l'eau")." et " ;
02272 echo b(" mon ami est en bateau").", la chaine ".vert("eau")." est une sous-chaine répétée. " ;
02273 echo " Dans les phrases " ;
02274 echo b("mon papa est dans un bateau") ;
02275 echo " et " ;
02276 echo b("pour mon tonton, il y a un souci").", " ;
02277 echo " la sous-séquence notée " ;
02278 echo rouge("mon") ;
02279 echo "*" ;
02280 echo rouge("un") ;
02281 echo ", qui signifie le mot ". rouge("mon")." suivi quelque part du mot ". rouge("un") ;
02282 echo ", est une sous-séquence répétée." ;
02283 echo " Ce genre de problème est classique lorsqu'on s'intéresse aux séquences d'ADN ou d'acides aminés." ;
02284 finp() ;
02285
02286 p("texte") ;
02287 echo "Là encore, la programmation en \"grande complexité\" (autre nom pour dire ".b("grande ampleur").") nécessite des approches algorithmiques différentes de " ;
02288 echo " la programmation classique. Ce sujet est beaucoup trop technique pour pouvoir être abordé dans un cours comme celui-ci" ;
02289 echo " qui est une ".em("petite")." introduction à la programmation classique, mais il est bon de savoir qu'il n'existe pas toujours des solutions " ;
02290 echo b("exactes")." et qu'on doit alors se contenter de ".b("résultats approchés").", d'".b("approximations")." souvent issues " ;
02291 echo " d'".href("https://fr.wikipedia.org/wiki/Heuristique_%28math%C3%A9matiques%29","heuristiques")." voire de " ;
02292 echo href("https://fr.wikipedia.org/wiki/M%C3%A9taheuristique","métaheuristiques")."..." ;
02293 finp() ;
02294
02295 finblockquote() ;
02296
02297 #######################################################################################################################
02298
02299 $tdmCRLM7->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # La récursivité
02300
02301 ## -------------------------------------------------------------------------------------------
02302
02303 blockquote() ;
02304
02305 p("texte") ;
02306 echo "Programmer, c'est écrire des programmes. De nombreux programmes utilisent des fonctions. " ;
02307 echo " Il y a parfois des façons \"naturelles\" ou \"élégantes\" de traiter un problème. Par exemple, voici une " ;
02308 echo " méthode de tri :" ;
02309 finp() ;
02310
02311 div("cadre") ;
02312 blockquote() ;
02313 p("aligne") ;
02314 echo em("Pour ".b("trier")." une liste de valeurs par ordre décroissant, il suffit de trouver le plus grand élément de la liste, ") ;
02315 echo em(" de l'afficher, puis de l'enlever de la liste et de ".b("trier")." la liste restante par ordre décroissant, jusqu'à ce qu'il ") ;
02316 echo em("n'y ait plus de valeurs à trier. ") ;
02317 finp() ;
02318 finblockquote() ;
02319 findiv() ;
02320
02321 p("texte") ;
02322 echo "Cette définition du tri qui fait référence à son propre tri se nomme un appel ".b("récursif").". Ecrire des fonctions " ;
02323 echo " récursives, savoir quand les utiliser et comment s'en passer ou comment les convertir en fonctions " ;
02324 echo " non récursives (lorsque c'est concrètement faisable) est une partie non négligeable de l'algorithmique traditionnelle. " ;
02325 echo " Pour aller plus loin dans ce sujet, on pourra consulter ";
02326 $l1 = "coursVivien.pdf" ;
02327 $a1 = "http://perso.ens-lyon.fr/frederic.vivien/Enseignement/Algo-2001-2002/Cours.pdf" ;
02328 $a2 = "http://fr.wikipedia.org/wiki/Fonction_d%27Ackermann" ;
02329 echo href($a1,"le cours d'algorithmique de F. Vivien").", chapitre 3 " ;
02330 echo "(".href($l1,"version locale").")" ;
02331 echo " et la définition de ".href("http://fr.wikipedia.org/wiki/Fonction_d%27Ackermann","la fonction d'Ackermann")." qui est, " ;
02332 echo " en principe, dérécursivable... " ;
02333
02334 finp() ;
02335
02336 finblockquote() ;
02337
02338 #######################################################################################################################
02339 #
02340 # progic8
02341 #
02342 #######################################################################################################################
02343
02344 $numcours = 8 ; partie($numcours) ; pvide() ;
02345 $rubrique = 0 ;
02346 $rubriques8 = array() ;
02347 $rubrique++ ; $rubriques8[$rubrique] = "But de cette section" ;
02348 $rubrique++ ; $rubriques8[$rubrique] = "Un comportement bizarre de R";
02349 $rubrique++ ; $rubriques8[$rubrique] = "Déboggage" ;
02350 $rubrique++ ; $rubriques8[$rubrique] = "Ecrire <<- n'est pas une faute de frappe" ;
02351 $rubrique++ ; $rubriques8[$rubrique] = "Profilage" ;
02352 $rubrique++ ; $rubriques8[$rubrique] = "Optimisation" ;
02353
02354 $tdmCRLM8 = new tdm($rubriques8) ;
02355 $tdmCRLM8->titre() ;
02356 $tdmCRLM8->menu("oui","oui","nou","p$numcours") ;
02357
02358 $numRub = 0 ;
02359
02360 #######################################################################################################################
02361
02362 $tdmCRLM8->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # But de cette section
02363
02364 ## -------------------------------------------------------------------------------------------
02365
02366 blockquote() ;
02367
02368 p() ;
02369 echo "Nous allons dans cette page essayer de répondre à trois questions :";
02370 finp() ;
02371
02372 ol() ;
02373
02374 debutli() ; p("texte") ;
02375 echo "Mon programme ne fonctionne pas comme je le voudrais." ;
02376 echo " Où est l'erreur ?" ;
02377 finp() ; finli() ;
02378
02379 debutli() ; p("texte") ;
02380 echo " Mon programme est lent. " ;
02381 echo " Quelle partie du code est la plus lente ?" ;
02382 finp() ; finli() ;
02383
02384 debutli() ; p("texte") ;
02385 echo "Comment accélérer le code qui est lent ?" ;
02386 finp() ; finli() ;
02387
02388 finol() ;
02389
02390 p("texte") ;
02391 echo "$R fournit des outils qui permettent de répondre aux deux premières questions " ;
02392 echo " car après tout, il ne s'agit que d'analyser le code du programme ou son exécution. Par contre, " ;
02393 echo " c'est à vous de modifier le code pour le rendre plus rapide sachant que de par " ;
02394 echo " sa conception, $R est \"lent\". " ;
02395 finp() ;
02396
02397 p("texte") ;
02398 echo "Il est aussi possible que votre problème à traiter \n" ;
02399 echo "soit un problème \"difficile\", NP-complet ou qu'il \"explose combinatoirement\", ce qui signifie \n" ;
02400 echo "que de toutes façons il sera très très long à exécuter (si vous avez le choix, n'hésitez pas \n" ;
02401 echo "à essayer de programmer ce genre de problèmes : comme c'est long, on peut passer beaucoup de \n" ;
02402 echo "temps à la machine à café sans culpabiliser de peur de rater la fin de l'exécution \n" ;
02403 echo "du programme !). \n" ;
02404 finp() ;
02405
02406 p("texte") ;
02407 echo "Nous essaierons de fournir pour cette dernière partie quelques pistes \n" ;
02408 echo " de solutions, lorsqu'il doit être possible d'accélérer l'exécution, ce qui n'est \n" ;
02409 echo "pas toujours le cas... \n" ;
02410 finp() ;
02411
02412 p("texte") ;
02413 echo "Mais commençons par un programme qui semble à la fois fonctionner et ne pas fonctionner, \n" ;
02414 echo "et qui, en tous cas, ne s'arrête pas dès le début de l'exécution. Il ne s'agit donc pas \n" ;
02415 echo "d'un problème simple à résoudre ou d'une erreur naïve de programmation. \n" ;
02416 finp() ;
02417
02418 finblockquote() ;
02419
02420 #######################################################################################################################
02421
02422 $tdmCRLM8->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Un comportement bizarre de R
02423
02424 ## -------------------------------------------------------------------------------------------
02425
02426 blockquote() ;
02427
02428 p("texte") ;
02429 echo "Il est rare qu'un programme \"marche\" du premier coup. Parfois, même si \n" ;
02430 echo "on est convaincu que $R va faire ce qu'on lui demande et qu'à la main \n" ;
02431 echo "on pense avoir résolu le problème, $R semble se comporter bizarrement. \n" ;
02432 finp() ;
02433
02434 p("texte") ;
02435 echo "Voici un exemple de programme un peu \"surprenant\". On demande à $R \n" ;
02436 echo "de créer une matrice avec deux lignes et deux colonnes. L'utilisateur peut \n" ;
02437 echo "alors supprimer la ligne ou la colonne de son choix et voir ce qu'il reste \n" ;
02438 echo "de la matrice. Mais bizarrement, $R a l'air de \"perdre\" la matrice \n" ;
02439 echo "avant la fin... \n" ;
02440 finp() ;
02441
02442 p("texte") ;
02443 echo "Le code $R associé, fourni ci-dessous, est court, simple à lire et à comprendre. \n" ;
02444 finp() ;
02445
02446 pre_fichier("bizar01.r","cadre") ;
02447
02448 p("texte") ;
02449 echo "Mais l'exécution de ce code est un peu \"mystérieuse\" : \n" ;
02450 finp() ;
02451
02452 pre_fichier("bizar02.txt","cadre") ;
02453
02454 p("texte") ;
02455 echo "Il semblerait que $R n'arrive plus à trouver le nombre de lignes et de colonnes \n" ;
02456 echo "de la matrice car au niveau de la dernière suppression, juste avant l'erreur, \n" ;
02457 echo "il y a affiché ".noir("\"avec lignes\"")." mais aucun nombre de lignes n'est affiché. \n" ;
02458 finp() ;
02459
02460 p("texte") ;
02461 echo "Pour un(e) professionnel(le) de $R , ce comportement est normal car \n" ;
02462 echo "il est décrit dans \n" ;
02463 echo "l'aide (longue, très longue) de la fonction ".hrrr("Extract","","[()")." et dans l'aide de la fonction ".hrrr("drop")."\n" ;
02464 echo "obtenues par ".noir("help(\"[\")")." et ".noir("help(drop)").". \n" ;
02465 finp() ;
02466
02467 p("texte") ;
02468 echo "Sauf que les explications -- en anglais -- ne sont pas très explicites : \n" ;
02469 finp() ;
02470
02471 pre_fichier("bizar04.txt","cadre") ;
02472
02473 p("texte") ;
02474 echo "Pour essayer de comprendre ce qui se passe, on peut tenter d'aller \n" ;
02475 echo " à la pêche (sous-entendu \"aux informations\") " ;
02476 echo " à l'aide de la fonction ".hrrr("print")." via ".noir("print(mat)")." \n" ;
02477 echo "ou de ".noir("print(nrow(mat))").". \n" ;
02478 echo "Cela se révèlera sans doute difficile et peu productif parce que si ".noir("x")." \n" ;
02479 echo "n'est pas une matrice, ".noir("nrow(x)")." renvoie ".noir("NULL").". \n" ;
02480 finp() ;
02481
02482 p("texte") ;
02483 echo "Est-ce un problème ? \n" ;
02484 echo "Oui, mais c'est un peu subtil. Si $R \n" ;
02485 echo "affiche bien ".noir("NULL")." pour ".noir("NULL")." avec ".noir("print()").", concaténer ".noir("NULL")." avec quelque chose \n" ;
02486 echo "transforme ".noir("NULL")." en chaine vide. De même, utiliser ".noir("NULL")." dans ".noir("cat()")." \n" ;
02487 echo "renvoie aussi la chaine vide, et du coup on ne voit plus rien. \n" ;
02488 finp() ;
02489
02490 p("texte") ;
02491 echo "Voici avec un exemple pourquoi il est difficile de comprendre ce qui se passe avec un simple ".noir("print()")." : \n" ;
02492 finp() ;
02493
02494 pre_fichier("bizar05.txt","cadre") ;
02495
02496 p("texte") ;
02497 echo "Donc si on ne voit rien avec un ".hrrr("print")." de notre objet, il faudrait \n" ;
02498 echo "sans doute essayer un ".noir("print(class(mat))").". Et là, miracle ! Voici la partie du code \n" ;
02499 echo "qui a été légèrement modifié \n" ;
02500 finp() ;
02501
02502 pre_fichier("bizar07.r","cadre") ;
02503
02504 p("texte") ;
02505 echo "et l'affichage de l'exécution : \n" ;
02506 finp() ;
02507
02508 pre_fichier("bizar06.txt","cadre") ;
02509
02510 p("texte") ;
02511 echo "Nous avons donc identifié le problème : la variable ".noir("mat")." change de nature. De \"matrix\" \n" ;
02512 echo "elle passe à \"integer\", ce qui signifie vecteur d'entiers. Avec un peu plus d'entrainement, \n" ;
02513 echo "c'était visible puisque $R avait écrit, avec un seul indice \n" ;
02514 finp() ;
02515
02516 pre_fichier("bizar08.txt","cadre") ;
02517
02518 p("texte") ;
02519 echo "au lieu de l'affichage classique des matrices, avec deux séries d'indices : \n" ;
02520 finp() ;
02521
02522 pre_fichier("bizar09.txt","cadre") ;
02523
02524 p("texte") ;
02525 echo "Mais quand on débute en $R , on n'est pas expert(e), bien sûr et ces subtilités d'affichage nous échappent \n" ;
02526 echo "souvent. \n" ;
02527 finp() ;
02528
02529 p("texte") ;
02530 echo "Nous avons donc identifié l'erreur, ou du moins nous avons cerné le problème. Pour le résoudre, \n" ;
02531 echo "l'aide de ".hrrr("Extract","","[()")." et de ".hrrr("drop")." indiquent clairement qu'il faut empêcher $R de réduire la dimension \n" ;
02532 echo "à l'aide du paramètre ".noir("drop").". \n" ;
02533 finp() ;
02534
02535 p("texte") ;
02536 echo "Donc en écrivant dans notre code \n" ;
02537 finp() ;
02538
02539 pre_fichier("bizar11.r","cadre") ;
02540
02541 p("texte") ;
02542 echo "le problème est résolu. Ouf ! \n" ;
02543 finp() ;
02544
02545 p("texte") ;
02546 echo "Enfin, presque... comme souvent en programmation. Car du coup notre boucle... boucle ! \n" ;
02547 echo "Il faut donc prévoir d'arrêter de demander à supprimer des lignes ou des colonnes s'il n'y en a \n" ;
02548 echo "plus, soit le code suivant juste avant la fin de la boucle tant que : \n" ;
02549 finp() ;
02550
02551 pre_fichier("bizar12.r","cadre") ;
02552
02553
02554 finblockquote() ;
02555
02556 #######################################################################################################################
02557
02558 $tdmCRLM8->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Déboggage
02559
02560 ## -------------------------------------------------------------------------------------------
02561
02562 blockquote() ;
02563
02564 p("texte") ;
02565 echo "Ce que nous venons de faire est un peu du \"bricolage\" : pour trouver ce qui ne va pas, nous avons \n" ;
02566 echo "ajouté des ".noir("print()")." et nous avons réexécuté le programme. \n" ;
02567 echo "$R dispose d'outils beaucoup plus professionnels pour suivre le comportement des fonctions. \n" ;
02568 finp() ;
02569
02570 p("texte") ;
02571 echo "La première fonction utile à ce sujet est sans doute ".hrrr("browser")." -- à ne pas confondre \n" ;
02572 echo "avec la fonction ".hrrr("browseURL","utils")." qui affiche une URL dans le navigateur. Mettre ".noir("browser()")." \n" ;
02573 echo "dans le corps d'une fonction permet d'interrompre momentanément l'exécution de la fonction en cours \n" ;
02574 echo "tout en ayant accès à $R . On peut donc taper des commandes, interroger les variables ou les modifier... \n" ;
02575 finp() ;
02576
02577 p("texte") ;
02578 echo "Lorsque $R exécute ".noir("browser()").", le prompt est modifié et affiche ".noir("Browse[n]").". \n" ;
02579 echo "Différentes commandes sont ajoutées à l'environnement habituel de $R. Ainsi \n" ;
02580 echo "".noir("n")." exécute juste une instruction, \n" ;
02581 echo "".noir("c")." quitte ce browser et reprend l'exécution de la fonction en cours à l'instruction suivante dans la fonction, \n" ;
02582 echo "".noir("f")." permet de terminer la boucle courante ou la fonction, \n" ;
02583 echo "".noir("Q")." quitte le browser et la fonction. \n" ;
02584 finp() ;
02585
02586 p("texte") ;
02587 echo "Pour éviter d'avoir à ajouter ".noir("browser()")." dans le code puis de l'enlever quand tout va bien -- il est sans doute \n" ;
02588 echo "plus prudent de le mettre en commentaire et de le décommenter pour le réutiliser au prochain \"bug\" -- $R fournit \n" ;
02589 echo "les fonctions ".hrrr("debug")." et ".hrrr("debug","","undebug").". Ecrire ".noir("debug(f)")." exécute systématiquement ".noir("browser()")." \n" ;
02590 echo "dès que la fonction ".noir("f")." est appelée. ".noir("undebug(f)")." vient annuler ce comportement. On peut se dispenser \n" ;
02591 echo "d'exécuter ".noir("undebug(f)")." si la fonction ".noir("f")." est redéfinie, par exemple si on lit son code dans un fichier... \n" ;
02592 finp() ;
02593
02594 p("texte") ;
02595 echo "Pour bien comprendre comment tout cela fonctionne, supposons que la boucle ".bleu("\"TANT QUE\"")." de notre exemple précédent \n" ;
02596 echo "soit dans la fonction ".noir("gereMatrice").", la matrice étant passée en paramètre. \n" ;
02597 finp() ;
02598
02599 p("texte") ;
02600 echo "Voici donc le code à dépanner : \n" ;
02601 finp() ;
02602
02603 pre_fichier("bizar14.r","cadre") ;
02604
02605 p("texte") ;
02606 echo "L'encadré suivant montre un exemple de session interactive qui permet de suivre ce que fait $R \n" ;
02607 echo "au niveau du déboggage \n" ;
02608 echo "(nous avons juste aménagé un peu le texte). On commence par indiquer à $R \n" ;
02609 echo "qu'on veut débugger notre fonction : \n" ;
02610 finp() ;
02611
02612 pre_fichier("bizar15.txt","cadre") ;
02613
02614 p("texte") ;
02615 echo "On utilise ensuite ".noir("n")." pour avancer dans l'exécution de la fonction. \n" ;
02616 echo "$R affiche chaque instruction avant de l'exécuter. Ici, nous avons appuyé 5 \n" ;
02617 echo "fois sur ".noir("n").", pour arriver à l'intérieur de la boucle : \n" ;
02618 finp() ;
02619
02620 pre_fichier("bizar16.txt","cadre") ;
02621
02622 p("texte") ;
02623 echo "Nous continuons l'exécution de la fonction avec des ".noir("n")." successifs, pour arriver juste avant \n" ;
02624 echo "l'exécution du code qui supprime une ligne ou une colonne : \n" ;
02625 finp() ;
02626
02627 pre_fichier("bizar17.txt","cadre") ;
02628
02629 p("texte") ;
02630 echo "Maintenant, interrogeons nos divers objets, exécutons la suppression et regardons la classe et le \n" ;
02631 echo "contenu de la matrice : \n" ;
02632 finp() ;
02633
02634 pre_fichier("bizar18.txt","cadre") ;
02635
02636 p("texte") ;
02637 echo "C'est fini, nous avons bien localisé l'endroit où $R change la matrice. Il reste à taper ".noir("Q")." \n" ;
02638 echo "puis ".noir("undebug(gereMatrice)")." pour revenir à un comportement \"normal\" de $R : \n" ;
02639 finp() ;
02640
02641 pre_fichier("bizar19.txt","cadre") ;
02642
02643 p("texte") ;
02644 echo "Il ne faut pas hésiter à recourir à la fonction ".hrrr("debug")." car c'est un outil très pratique \n" ;
02645 echo "qui permet de localiser les erreurs. De plus, $rstudio \n" ;
02646 echo "fournit un environnement adapté à ".noir("debug()")." avec des boutons pour les actions \n" ;
02647 echo "".noir("c").", ".noir("n")."... et le panneau de droite montre les variables locales... \n" ;
02648 echo "A l'usage, c'est beaucoup plus complet et beaucoup plus pratique que le mode session de l'interface \n" ;
02649 echo "standard de $R. \n" ;
02650 finp() ;
02651
02652 finblockquote() ;
02653
02654 #######################################################################################################################
02655
02656 $tdmCRLM8->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Ecrire <<- n'est pas une faute de frappe
02657
02658 ## -------------------------------------------------------------------------------------------
02659
02660 blockquote() ;
02661
02662 p("texte") ;
02663 echo "Il arrive parfois les programmes soient longs à s'exécuter et nous essaierons de gérer ce \n" ;
02664 echo "problème dans la section suivante. Il arrive aussi qu'un programme s'exécute sans erreur apparente mais avec \n" ;
02665 echo "un résultat faux au bout du compte. Pour peu qu'il y ait beaucoup de résultats intermédiaires, ou beaucoup \n" ;
02666 echo "de variables et beaucoup de fonctions, la technique précédente avec ".noir("debug()")." et ".noir("browser")." est parfois un peu \n" ;
02667 echo "\"lourde\" à utiliser, en particulier parce qu'il s'agit d'un environnement local. Une fois ".noir("debug()")." quitté, les \n" ;
02668 echo "variables locales utilisées par la fonction ont disparu. \n" ;
02669 finp() ;
02670
02671 p("texte") ;
02672 echo "$R fournit avec l'instruction ".noir("<<-")." un moyen intéressant de \"sauvegarder\" des variables. \n" ;
02673 finp() ;
02674
02675 p("texte") ;
02676 echo "Mais commençons par regarder cette disparition des variables. \n" ;
02677 echo "Par défaut, toute variable dans une fonction est locale, ce qu'on peut voir avec le code suivant \n" ;
02678 finp() ;
02679
02680 pre_fichier("vars01.r","cadre") ;
02681
02682 p("texte") ;
02683 echo "dont l'exécution fournit : \n" ;
02684 finp() ;
02685
02686 pre_fichier("vars01.txt","cadre") ;
02687
02688 p("texte") ;
02689 echo "Une fonction l'exécution terminée, on n'a plus accès aux variables définies dans la fonction. \n" ;
02690 echo "Si on écrit ".noir("<<-")." au lieu de ".noir("<-").", $R vient écrire la variable dans l'environnement \n" ;
02691 echo "parent donc pour nous ici dans l'environnement global. Ainsi avec \n" ;
02692 finp() ;
02693
02694 pre_fichier("vars02.r","cadre") ;
02695
02696 p("texte") ;
02697 echo "on obtient : \n" ;
02698 finp() ;
02699
02700 pre_fichier("vars02.txt","cadre") ;
02701
02702 p("texte") ;
02703 echo "Il est clair que pour notre exemple, cela ne sert pas à grand-chose. Pour un exemple en vraie grandeur, \n" ;
02704 echo "utiliser ".noir("<<-")." dans le corps de la fonction, ou même à l'intérieur de ".noir("debug()")." \n" ;
02705 echo "peut permettre de sauvegarder les \"grosses\" variables (listes nommées, data frame construits progressivement...) \n" ;
02706 echo "dans différents états au cours de l'exécution afin de pouvoir comparer après coup les structures, \n" ;
02707 echo "ou même simplement pour \n" ;
02708 echo "documenter ce qui se passe en \n" ;
02709 echo "début, en cours et en fin d'exécution... \n" ;
02710 finp() ;
02711
02712 finblockquote() ;
02713
02714 #######################################################################################################################
02715
02716 $tdmCRLM8->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Profilage
02717
02718 ## -------------------------------------------------------------------------------------------
02719
02720 blockquote() ;
02721
02722 p("texte") ;
02723 echo "Une fois que les programmes sont justes et qu'il s'exécutent \"bien\", on peut vouloir \n" ;
02724 echo "qu'ils s'exécutent \"vite\". Mais d'où vient la lenteur de notre code ? \n" ;
02725 finp() ;
02726
02727 p("texte") ;
02728 echo "Imaginons qu'on ait deux fonctions appelées à l'intérieur d'un programme. La lenteur \n" ;
02729 echo "vient peut-être de la première fonction, ou de la deuxième ou peut-être même \n" ;
02730 echo "des autres parties du programme. Pour tester cela, $R fournit en standard plusieurs fonctions, \n" ;
02731 echo "dont ".hrrr("Rprof","utils")." et ".hrrr("summaryRprof","utils").". \n" ;
02732 finp() ;
02733
02734 p("texte") ;
02735 echo "Voici comment les utiliser : on lance ".noir("Rprof()").", on exécute le code et ensuite \n" ;
02736 echo "on demande à $R via ".noir("summaryRprof()")." d'afficher les résultats du profilage. \n" ;
02737 finp() ;
02738
02739 p("texte") ;
02740 echo "Imaginons par exemple qu'une fonction ".noir("h()")." \n" ;
02741 echo "appelle la fonction ".noir("f()")." \n" ;
02742 echo "et \n" ;
02743 echo "la fonction ".noir("g()").", comme dans le code du fichier \n" ;
02744 echo href("lent01.r")." suivant \n" ;
02745 finp() ;
02746
02747 pre_fichier("lent01.r","cadre") ;
02748
02749 p("texte") ;
02750 echo "Voici le code à utiliser pour analyser notre fonction ".noir("h()")." \n" ;
02751 finp() ;
02752
02753 pre_fichier("lent02.r","cadre") ;
02754
02755 p("texte") ;
02756 echo "Et son résultat sachant que les durées sont exprimées en secondes : \n" ;
02757 finp() ;
02758
02759 pre_fichier("lent02.txt","cadre") ;
02760
02761 p("texte") ;
02762 echo "Les quatre dernières lignes de l'affichage de ".noir("\$by.total")." \n" ;
02763 echo "montrent clairement que les fonctions \n" ;
02764 echo "".noir("f()")." et \n" ;
02765 echo "".noir("c()")." \n" ;
02766 echo "prennent beaucoup plus de temps à s'exécuter que les fonctions \n" ;
02767 echo "".noir("+()")." et \n" ;
02768 echo "".noir("g()").". \n" ;
02769 finp() ;
02770
02771 p("texte") ;
02772 echo "Pour tester plus finement du code, on peut utiliser le package nommé \n" ;
02773 echo hrrp("microbenchmark").". Par exemple, est-il plus rapide de générer un vecteur \n" ;
02774 echo "de valeurs numériques suivant une loi uniforme ou une loi normale ? \n" ;
02775 echo "Voici le code qui donne la réponse (il est plus lent de générer des données normales), avec son exécution : \n" ;
02776 finp() ;
02777
02778 pre_fichier("microb01.txt","cadre") ;
02779
02780 p("texte") ;
02781 echo "De même, nous avions écrit qu'il vaut mieux éviter de réaliser \n" ;
02782 echo "le même appel de fonction si les paramètres ne changent pas. Voici \n" ;
02783 echo "un exemple chronométré de ce que cela signifie. \n" ;
02784 finp() ;
02785
02786 p("texte") ;
02787 echo "Soit le code $R suivant à évaluer : \n" ;
02788 finp() ;
02789
02790 pre_fichier("microb02.r","cadre") ;
02791
02792 p("texte") ;
02793 echo "Pour comprendre qu'il ne s'agit que d'une évaluation du temps passé, voici deux \n" ;
02794 echo "exécutions de ce programme : \n" ;
02795 finp() ;
02796
02797 pre_fichier("microb02.txt","cadre") ;
02798
02799 p("texte") ;
02800 echo "A la lecture de ces résultats, la fonction ".noir("f")." est bien plus lente que la fonction ".noir("g")." : \n" ;
02801 echo "il ne faut donc pas calculer plusieurs fois \n" ;
02802 echo "".noir("max(v)")." mais bien mettre cette valeur dans une variable comme ".noir("maxv").". \n" ;
02803 finp() ;
02804
02805 p("texte") ;
02806 echo "On peut aussi vouloir s'intéresser non pas aux fonctions mais aux lignes de code. \n" ;
02807 echo "Le package ".bleu("lineprof")." permet un tel profilage et fournit un affichage adapté. \n" ;
02808 finp() ;
02809
02810 p("texte") ;
02811 echo rouge("Attention ").": ce package n'est pas \n" ;
02812 echo "disponible directement via le ".href("https://cran.r-project.org/","CRAN")." mais via ".href("https://github.com","github")." seulement. \n" ;
02813 echo " Il utilise le package ".hrrp("shiny")." pour un affichage interactif dans le navigateur. \n" ;
02814 finp() ;
02815
02816 p("texte") ;
02817 echo "Pour installer ce package ".bleu("lineprof").", il faut \n" ;
02818 echo "écrire (sous réserve, donc, que le package ".hrrp("devtools")." soit installé au préalable) : \n" ;
02819 finp() ;
02820
02821 pre_fichier("lineprof01.txt","cadre") ;
02822
02823 p("texte") ;
02824 echo "Admettons par exemple que l'on veuille analyser les lignes du code suivant : \n" ;
02825 finp() ;
02826
02827 pre_fichier("lent04.r","cadre") ;
02828
02829 p("texte") ;
02830 echo "Pour cela, on écrit \n" ;
02831 finp() ;
02832
02833 pre_fichier("lineprof01.r","cadre") ;
02834
02835 p("texte") ;
02836 echo "Et on obtient dans le navigateur par défaut : \n" ;
02837 finp() ;
02838
02839 $img = "lineprof.png" ;
02840 p() ;
02841 echo href($img,img($img)) ;
02842 finp() ;
02843
02844 p("texte") ;
02845 echo "Il est facile de voir que la ligne 8 est la plus \"consommatrice\". \n" ;
02846 finp() ;
02847
02848 finblockquote() ;
02849
02850 #######################################################################################################################
02851
02852 $tdmCRLM8->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Optimisation
02853
02854 ## -------------------------------------------------------------------------------------------
02855
02856 blockquote() ;
02857
02858 p("texte") ;
02859 echo "Maintenant que nous savons quelle partie de code est lente, \n" ;
02860 echo "comment aller plus vite ? \n" ;
02861 finp() ;
02862
02863 p("texte") ;
02864 echo "C'est une question compliquée car il est possible que la méthode soit lente : si vous \n" ;
02865 echo "avez décidé, par exemple, de passer en revue toutes les sous-chaines de caractères d'un génome humain, ce \n" ;
02866 echo "sera forcément assez long, disons plusieurs dizaines de minutes sans doute. \n" ;
02867 finp() ;
02868
02869 p("texte") ;
02870 echo "Donc nous allons supposer que le code est \"bon\" mais lent. Une fois repérées les parties vraiment \n" ;
02871 echo "lentes grâce à la section précédente, il faut essayer d'appliquer \n" ;
02872 echo "quelques grands principes pour éviter qu'un code ne soit lent. Si ce n'est pas suffisant, \n" ;
02873 echo "il faudra analyser si la lenteur vient du langage, en interne, ou si cela vient de notre façon de coder. \n" ;
02874 finp() ;
02875
02876 p("texte") ;
02877 echo "Tout d'abord, comme nous \n" ;
02878 echo "venons de le voir, un premier grand principe est qu'il ne faut pas \n" ;
02879 echo "effectuer deux fois le même calcul déterministe sur une structure si elle \n" ;
02880 echo "ne change pas. \n" ;
02881 finp() ;
02882
02883 p("texte") ;
02884 echo "Donc si on utilise une boucle ".bleu("POUR").", par exemple, il faut enlever tous les \n" ;
02885 echo "calculs comme ".noir("3*h")." si ".noir("h")." ne dépend pas de l'indice de boucle... \n" ;
02886 finp() ;
02887
02888 p("texte") ;
02889 echo "Ensuite, il faut essayer d'utiliser les fonctions vectorielles de $R plutôt que \n" ;
02890 echo "de réécrire soi-même les calculs. \n" ;
02891 finp() ;
02892
02893 p("texte") ;
02894 echo "Voici par exemple pourquoi il ne faut pas \n" ;
02895 echo "réinventer la somme d'un vecteur : \n" ;
02896 finp() ;
02897
02898 pre_fichier("sum01.txt","cadre") ;
02899
02900 p("texte") ;
02901 echo "Un deuxième grand principe est qu'il ne faut pas laisser $R gérer la mémoire. \n" ;
02902 echo "Malheureusement, ce n'est pas toujours facile de savoir quand $R recopie les variables en mémoire. \n" ;
02903 echo "Disons, pour simplifier, qu'il est prudent de prévoir au maximum les tailles des \n" ;
02904 echo "tableaux résultats, de les initialiser et ensuite de les remplir. " ;
02905 finp() ;
02906
02907 p("texte") ;
02908 echo " Imaginons par exemple \n" ;
02909 echo "que l'on veuille calculer ".b("n")." nombres \"simples\", par exemple tous les nombres de 1 à ".noir("n").". \n" ;
02910 finp() ;
02911
02912 p("texte") ;
02913 echo "Si vous écrivez cela en concaténant chaque nouveau nombre au vecteur précédent des résultats, soit le code \n" ;
02914 finp() ;
02915
02916 pre_fichier("de1an01.r","cadre") ;
02917
02918 p("texte") ;
02919 echo "alors $R viendra de temps en temps ou peut-être même à chaque fois recopier le vecteur ".noir("v")." \n" ;
02920 echo "en mémoire. Il est beaucoup plus efficace de prévoir un vecteur de la \"bonne taille\" (voir l'exercice \n" ;
02921 echo "3 associé à cette page qui explicite les stratégies possibles lorsqu'il n'est pas possible de prévoir avant l'exécution \n" ;
02922 echo "la taille des résultats) et de le remplir au fur et à mesure, soit le code : \n" ;
02923 finp() ;
02924
02925 pre_fichier("de1an02.r","cadre") ;
02926
02927 p("texte") ;
02928 echo "Mais de toutes façons ce ne sera jamais aussi efficace que le code $R natif et vectoriel : \n" ;
02929 finp() ;
02930
02931 pre_fichier("de1an03.r","cadre") ;
02932
02933 p("texte") ;
02934 echo "En voici la preuve, avec une machine qui a beaucoup de mémoire. Nous avons pris la précaution \n" ;
02935 echo "de vérifier que l'ordre des instructions ne perturbe pas les résultats (à cause des \n" ;
02936 echo "encombrements mémoire successifs) : \n" ;
02937 finp() ;
02938
02939 pre_fichier("de1an04.txt","cadre") ;
02940
02941 finblockquote() ;
02942
02943 #######################################################################################################################
02944 #
02945 # progic9
02946 #
02947 #######################################################################################################################
02948
02949 $numcours = 9 ; partie($numcours) ; pvide() ;
02950 $rubrique = 0 ;
02951 $rubriques9 = array() ;
02952 $rubrique++ ; $rubriques9[$rubrique] = "Programmation, choix, tests, déboggage et profilage " ;
02953 $rubrique++ ; $rubriques9[$rubrique] = "Programmation, spécifications et documentations" ;
02954 $rubrique++ ; $rubriques9[$rubrique] = "Mises à jour, maintenances, objets et packages" ;
02955 $rubrique++ ; $rubriques9[$rubrique] = "Programmation et Interfaçage " ;
02956 $rubrique++ ; $rubriques9[$rubrique] = "Conclusion" ;
02957
02958 $tdmCRLM9 = new tdm($rubriques9) ;
02959 $tdmCRLM9->titre() ;
02960 $tdmCRLM9->menu("oui","oui","nou","p$numcours") ;
02961
02962 # exercices($numcours) ;
02963
02964 $numRub = 0 ;
02965
02966 #######################################################################################################################
02967
02968 $tdmCRLM9->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Programmation, choix, tests, déboggage et profilage
02969
02970 ## -------------------------------------------------------------------------------------------
02971
02972 blockquote() ;
02973
02974 p("texte") ;
02975 echo "Programmer, c'est écrire des programmes. Soit. Mais comment être sûr que les programmes sont justes ?" ;
02976 echo " Et que les autres sauront les utiliser ?" ;
02977 echo " Après réflexion, ce n'est pas si simple... " ;
02978 finp() ;
02979
02980 p("texte") ;
02981 echo "Prenons un exemple concret, celui de la conversion de et vers des pouces en cm : une fois que l'on sait " ;
02982 echo "qu'".b("un pouce fait 2,54 cm").", tout n'est pas dit. Ainsi, comment entrer les valeurs et l'unité ?" ;
02983 echo " Faut-il écrire une fonction qui pose une question, lit la réponse au clavier en session $R, ou passer ces valeurs " ;
02984 echo " en paramètres, ou utiliser un formulaire Tcl/Tk, voire une interface Web ?" ;
02985 finp() ;
02986
02987 p("texte") ;
02988 echo "Admettons un instant que l'on s'en tienne au premier choix, à savoir la lecture au clavier -- ce qui sans doute pas une bonne " ;
02989 echo " solution, ce que l'on verra plus loin." ;
02990 echo " Voici un exemple de programme. Voyez-vous l'erreur de programmation ?" ;
02991 finp() ;
02992
02993 pre_fichier("pouce1.r","cadrebleu") ;
02994
02995 p("texte") ;
02996 echo "Une lecture rapide du programme et le test avec un cas \"idéal\" comme ci-dessous :" ;
02997 finp() ;
02998
02999 pre_fichier("pouce1.sor","cadrejaune") ;
03000
03001 p("texte") ;
03002 echo "ne permet pas de prouver que le programme est juste. Cela montre seulement que si on fournit les bons " ;
03003 echo " paramètres (en type et en valeur), le calcul est correct. Oui mais, si on saisit ".b("pouce")." au lieu de " ;
03004 echo b("pouces").", c'est-à-dire sans le ".b("s")." à la fin, que fait le programme ?" ;
03005 echo em(" Stricto sensu").", ".b("pouce")." et ".b("pouces")." ne sont pas égaux donc le programme fait la conversion " ;
03006 echo " dans le mauvais sens. " ;
03007 finp() ;
03008
03009 p("texte") ;
03010 echo "Une version plus fiable serait donc " ;
03011 finp() ;
03012
03013 pre_fichier("pouce2.r","cadrebleu") ;
03014
03015 p("texte") ;
03016 echo "Maintenant, pourquoi ne tester que l'unité ? " ;
03017 echo " Avec un utilisateur pressé, ou le clavier numérique désactivé, la saisie de la valeur peut être vide. " ;
03018 echo " Dans ce cas, la variable valeur contient ".b("NA")." car la fonction ".hrrr("numeric","","as.numeric()")." ne renvoie pas " ;
03019 echo " d'erreur. " ;
03020 finp() ;
03021
03022 p("texte") ;
03023 echo "Ecrire un programme juste, c'est à la fois penser aux erreurs possibles, les détecter et les gérer. " ;
03024 echo " On peut décider de boucler sur la saisie d'une valeur numérique ou quitter le programme dès la première " ;
03025 echo " saisie si la valeur n'est pas numérique... ".rouge("Programmer, c'est donc faire des choix").". " ;
03026 finp() ;
03027
03028 p("texte") ;
03029 echo "Programmer, c'est aussi ".b("tester")." les divers cas possibles que l'on a recensé. C'est pourquoi la " ;
03030 echo " saisie au clavier est une mauvaise solution. Car il faudra taper les réponses à chaque fois que l'on " ;
03031 echo " veut vérifier que ce qu'on a écrit est correct. Une solution plus \"propre\" et qui correspond plus à " ;
03032 echo " l'esprit de $R est de définir une fonction de conversion avec les deux paramètres :" ;
03033 finp() ;
03034
03035 pre_fichier("pouce3.r","cadrebleu") ;
03036
03037
03038 p("texte") ;
03039 echo "L'intérêt, c'est que maintenant on peut demander à $R de tester les cas possibles juste en " ;
03040 echo " éxécutant le script suivant :" ;
03041 finp() ;
03042
03043 pre_fichier("pouce4.r","cadrebleu") ;
03044
03045 p("texte") ;
03046 echo "Voici ce qu'on obtient alors :" ;
03047 finp() ;
03048
03049 pre_fichier("pouce4.res","cadrejaune") ;
03050
03051
03052 p("texte") ;
03053 echo "Si on veut vraiment saisir les informations au clavier, on écrira une autre fonction " ;
03054 echo " par exemple, ".b("saisieConversion()")." qui renvoie les deux valeurs. Du coup, on peut écrire " ;
03055 echo b("convPouceCm( saisieConversion() )")." pour exécuter les deux actions " ;
03056 finp() ;
03057
03058 pre_fichier("pouce5.r","cadrebleu") ;
03059
03060 p("texte") ;
03061 echo "Au passage, on pourrait améliorer la fonction ".b("convPouceCm()")." en prévoyant une unité par défaut, " ;
03062 echo " un affichage par défaut avec deux décimales, le choix de l'affichage ou non, le renvoi du résultat, " ;
03063 echo " ce qui permettrait de tester le programme avec lui-même : " ;
03064 finp() ;
03065
03066 pre_fichier("pouce6.res","cadrebleu") ;
03067
03068 p("texte") ;
03069 echo "Lorsque le programme écrit est d'importance, il est essentiel de pouvoir vérifier chaque calcul " ;
03070 echo " intermédiaire, de pouvoir suivre le détail à l'intérieur de chaque boucle, ou au contraire, de " ;
03071 echo " pouvoir tout exécuter jusqu'à une partie délicate. " ;
03072 echo " De même, si la vitesse d'exécution du programme est mauvaise, il faut pouvoir analyser le " ;
03073 echo " comportement du programme, savoir où $R «perd du temps», ce qui le ralentit..." ;
03074 echo " $R et $rstudio disposent de fonctions pour cela, heureusement. " ;
03075 #echo " Voir ".href("progie8.php?solutions=0#tdm1","l'exercice 1 de cette section")." pour plus de détails. " ;
03076 finp() ;
03077
03078 finblockquote() ;
03079
03080 #######################################################################################################################
03081
03082 $tdmCRLM9->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Programmation, spécifications et documentations
03083
03084 ## -------------------------------------------------------------------------------------------
03085
03086 blockquote() ;
03087
03088 p("texte") ;
03089 echo "Ce que montre la section précédente, c'est qu'il faut bien détailler ce que l'on veut faire, " ;
03090 echo " bien préciser les entrées, les sorties. Autoriser ".b("p")." ou ".b("i")." ou ".b("d")." comme " ;
03091 echo " abbréviation [internationale] légale de ".b("pouces")." est sans doute une bonne idée car on dit " ;
03092 echo em("inch")." en anglais et ".em("Daumen")." en allemand. Fournir le code-source de la conversion ou le " ;
03093 echo " rendre accessible sur Internet c'est offrir la possibilité aux autres de le lire et peut-être vous " ;
03094 echo " aider à l'améliorer (il vaut mieux alors mettre les commentaires en anglais, malheureusement)." ;
03095 finp() ;
03096
03097 p("texte") ;
03098 echo "Si on n'écrit pas une fonction mais un ensemble de fonctions, il est conseillé de fournir des exemples " ;
03099 echo " d'utilisation, un petit manuel pour rappeler les options, détailler le format des structures utilisées. " ;
03100 echo " Si cela met en jeu des fichiers de données, il est d'usage de fournir des exemples de tels fichiers, pour " ;
03101 echo " qu'une personne qui n'a pas écrit ces fonctions arrive à les utiliser et à comprendre comment elles " ;
03102 echo " fonctionnent juste à la lecture de l'aide. " ;
03103 finp() ;
03104
03105 p("texte") ;
03106 echo "Si c'est encore plus complexe, il faut carrément écrire un livre pour expliquer tout cela en détail, comme " ;
03107 echo " par exemple avec ces deux ouvrages :" ;
03108 finp() ;
03109
03110 blockquote() ;
03111 table(0,15) ;
03112
03113 tr() ;
03114 td("C") ;
03115 echo href("http://www.springer.com/life+sciences/evolutionary+%26+developmental+biology/book/978-1-4614-1742-2",img("paradis.jpg","",100)) ;
03116 fintd() ;
03117 td() ; fintd() ;
03118 td("C") ;
03119 echo href("http://www.springer.com/statistics/life+sciences%2C+medicine+%26+health/book/978-0-387-77239-4",img("hahne.jpg","",100)) ;
03120 fintd() ;
03121 fintr() ;
03122
03123 tr() ;
03124 td("C") ;
03125 echo href("http://www.springer.com/life+sciences/evolutionary+%26+developmental+biology/book/978-1-4614-1742-2","Paradis") ;
03126 fintd() ;
03127 td() ; fintd() ;
03128 td("C") ;
03129 echo href("http://www.springer.com/statistics/life+sciences%2C+medicine+%26+health/book/978-0-387-77239-4","Hahne") ;
03130 fintd() ;
03131 fintr() ;
03132
03133 fintable() ;
03134 finblockquote() ;
03135
03136 finblockquote() ;
03137
03138 #######################################################################################################################
03139
03140 $tdmCRLM9->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Mises à jour, maintenances, objets et packages
03141
03142 ## -------------------------------------------------------------------------------------------
03143
03144 blockquote() ;
03145
03146 p("texte") ;
03147 echo "Il est fréquent qu'on ne pense pas tout de suite à tout, qu'on vienne ajouter des fonctionnalités au fur et à " ;
03148 echo " mesure de l'utilisation des programmes. C'est pourquoi il est important de bien gérer les numéros de version, " ;
03149 echo " de noter ce qui change (il faut parfois défaire ce qui a été fait et revenir à une version antérieure). " ;
03150 echo " Dans certains cas, notamment quand ce qu'on écrit dépend des packages de $R, il faut parfois modifier le code " ;
03151 echo " par ce que $R a changé ou par ce que le package a changé." ;
03152 finp() ;
03153
03154 p("texte") ;
03155 echo "Les tests cités dans la section précédente doivent alors permettre de prouver que malgré les changements les ";
03156 echo " programmes font comme avant et même plus qu'avant. La rétrocompatibilité et la fiabilité sont des " ;
03157 echo " concepts à retenir et à implémenter." ;
03158 finp() ;
03159
03160 p("texte") ;
03161 echo "La maintenance du code peut parfois se limiter à la traduction des messages dans différentes langues, à ajouter des " ;
03162 echo " paramètres, mais elle peut parfois être beaucoup plus lourde, par exemple quand on vient ".b("factoriser")." du " ;
03163 echo " code, c'est-à-dire mettre des parties en commun via des sous-programmes qui couvrent plusieurs cas. " ;
03164 finp() ;
03165
03166 p("texte") ;
03167 echo "Ces quelques séances d'initiation à la ".b("programmation élementaire")." ne peuvent pas, bien sûr, présenter " ;
03168 echo " des concepts plus techniques comme les objets et l'écriture de packages. Nous renvoyons pour cela aux exercices " ;
03169 echo " de cettes section afin d'avoir une petite idée de ce que cela met en jeu." ;
03170 finp() ;
03171
03172 finblockquote() ;
03173
03174 #######################################################################################################################
03175
03176 $tdmCRLM9->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Programmation et Interfaçage
03177
03178 ## -------------------------------------------------------------------------------------------
03179
03180 blockquote() ;
03181
03182 p("texte") ;
03183 echo "La notion d'".b("interface")." correspond à deux choses bien distinctes : les interfaces utilisateurs et " ;
03184 echo " les interfaces de programmation. Dans le premier cas, il s'agit de savoir comment l'utilisateur interagit avec les " ;
03185 echo " fonctions et les programmes (en ligne de commande, par script, par menus, par panneaux...). " ;
03186 echo " Dans le second cas, il s'agit de faire dialoguer entre eux les langages, d'appeler du C via R, par exemple, " ;
03187 echo " ou de demander à Python ou Ruby d'exécuter du R. On pourra consulter les liens ci-dessous pour voir des " ;
03188 echo " exemples possibles d'interface de programmation." ;
03189 finp() ;
03190
03191 p("texte") ;
03192 nbsp(10) ;
03193 echo hrrp("Rcpp") ;
03194 nbsp(10) ;
03195 echo href("http://rpy.sourceforge.net/","R py2","gvert") ;
03196 nbsp(10) ;
03197 echo href("https://sites.google.com/a/ddahl.org/rinruby-users/Home","R in Ruby","grouge") ;
03198 finp() ;
03199
03200 p("texte") ;
03201 echo "Au niveau des interfaces utilisateur, à part des interfaces générales avec menus comme " ;
03202 echo href("https://rkward.kde.org/","Rkward") ;
03203 echo " et " ;
03204 echo href("http://www.rcommander.com/","Rcmdr").", " ;
03205 echo " $R fournit un package nommé ".hrrp("tcltk") ;
03206 echo " qui permet de développer des " ;
03207 echo href("http://fr.wikipedia.org/wiki/Interface_graphique","GUI")." et un package nommé " ;
03208 echo " ".hrrp("shiny")." pour définir des interfaces web." ;
03209 echo " Ainsi le code suivant " ;
03210 finp() ;
03211
03212 pre_fichier("pouceGUI.r","cadrebleu") ;
03213
03214 p("texte") ;
03215 echo " fournit une interface graphique minimale (et mal présentée) pour la saisie des deux paramètres dans la conversion pouces/cm..." ;
03216 finp() ;
03217
03218 p() ;
03219 nbsp(10) ;
03220 $img = "pouceGUI.png" ;
03221 echo href($img,img($img,"",300)) ;
03222 finp() ;
03223
03224
03225 p("texte") ;
03226 echo "Pour " ;
03227 echo " ".href("https://shiny.rstudio.com/tutorial/","shiny").", on écrit deux scripts : celui du serveur, " ;
03228 echo " nommé ".b("server.R")." et celui de l'interface, nommé ".b("ui.R").". Voir par exemple la démonstration " ;
03229 echo " dans la ".href("https://shiny.rstudio.com/gallery/","gallerie de Shiny") ;
03230 echo " nommée ".href("https://shiny.rstudio.com/gallery/kmeans-example.html","Iris k-means clustering")."... " ;
03231 finp() ;
03232
03233 finblockquote() ;
03234
03235 #######################################################################################################################
03236
03237 $tdmCRLM9->afficheSousRubrique("p$numcours","oui") ; $numRub++ ; # Conclusion
03238
03239 ## -------------------------------------------------------------------------------------------
03240
03241 blockquote() ;
03242
03243 p("texte") ;
03244 echo "Les quelques heures passées à écrire des scripts $R et à lire les corrigés des exercices " ;
03245 echo " vous auront sans doute convaincu(e) que :" ;
03246 finp() ;
03247
03248 ul() ;
03249
03250 debutli() ;
03251 p("texte") ;
03252 echo "programmer, c'est ".bleu("assez facile au début").", pour des petits calculs" ;
03253 echo " ;" ;
03254 finp() ;
03255 finli() ;
03256
03257 debutli() ;
03258 p("texte") ;
03259 echo "tout le monde peut programmer, mais ".rouge("bien programmer est un art") ;
03260 echo " ;" ;
03261 finp() ;
03262 finli() ;
03263
03264 debutli() ;
03265 p("texte") ;
03266 echo "programmer demande de la rigueur, de la constance et de l'endurance ; " ;
03267 echo "en d'autres termes, programmer peut se révéler fastidieux et devenir " ;
03268 echo b("intrinsèquement rébarbatif")." (pour ne pas dire ch*...)" ;
03269 echo " ;" ;
03270 finp() ;
03271 finli() ;
03272
03273 debutli() ;
03274 p("texte") ;
03275 echo " programmer demande de la méthode, de la réflexion et du temps" ;
03276 echo " ;" ;
03277 finp() ;
03278 finli() ;
03279
03280 debutli() ;
03281 p("texte") ;
03282 echo " programmer peut se révéler ".vert("agréable")." car cela fait plaisir d'avoir réussi à créer " ;
03283 echo " quelque chose qui résoud un problème ou qui fait le travail en automatique à notre place." ;
03284 finp() ;
03285 finli() ;
03286
03287 finul() ;
03288
03289 p("texte") ;
03290 echo "Alors, un seul mot : tous et toutes à vos papier et crayon avant de passer au clavier !" ;
03291 finp() ;
03292
03293 finblockquote() ;
03294
03295 #######################################################################################################################
03296
03297 pvide() ;
03298 p() ;
03299 echo href("montresource.php?nomfic=tutrprog.php","Code-source php de cette page. ","orange_stim nou") ;
03300 finp() ;
03301
03302 #######################################################################################################################
03303
03304 finSection() ;
03305 finPage() ;
03306 ?>
Pour ne pas voir les numéros de ligne, ajoutez &nl=non à la suite du nom du fichier.
Retour à la page principale de (gH)