Listing du fichier progie5.php
00001 <?php
00002 # # (gH) -_- progie5.php ; TimeStamp (unix) : 16 Février 2015 vers 21:26
00003
00004 error_reporting(E_ALL | E_NOTICE | E_STRICT) ;
00005
00006 include_once("std7.php") ;
00007 include_once("progi.php") ;
00008 include_once("statuno7.php") ;
00009
00010 $R = s_span("R","gbleuf") ;
00011 $numSerie = 5 ;
00012 debutPageExercices($numSerie) ;
00013
00014 ## -------------------------------------------------------------------------------------------
00015
00016 p("texte") ;
00017 echo "" ;
00018 finp() ;
00019 debutSection() ;
00020
00021 $tableauDesRubriques = array() ;
00022 $idr = 0 ;
00023
00024 $idr++; $tableauDesRubriques[$idr] = "Soulignés et encadrés" ;
00025 $idr++; $tableauDesRubriques[$idr] = "Utilisation de ".rouge("sink()")." et ".rouge("source()") ;
00026 $idr++; $tableauDesRubriques[$idr] = "Une fonction pour attendre" ;
00027 $idr++; $tableauDesRubriques[$idr] = "Reproduire la fonction ".noir("ifelse") ;
00028 $idr++; $tableauDesRubriques[$idr] = "Une fonction anonyme pour gérer les NA ?" ;
00029 $idr++; $tableauDesRubriques[$idr] = "Formater l'affichage d'un data frame" ;
00030 $idr++; $tableauDesRubriques[$idr] = "Bien afficher ".noir("par()")." et ".noir("options()") ;
00031
00032 $tdmCRLM = new tdm($tableauDesRubriques) ;
00033 $tdmCRLM->titre() ;
00034 $tdmCRLM->menu("oui","oui","nou") ;
00035
00036 afficherSolutions($numSerie) ;
00037
00038 finSection() ;
00039
00040 debutSection() ;
00041 $numExo = 0 ;
00042
00043 ## -------------------------------------------------------------------------------------------
00044
00045 $tdmCRLM->afficheRubrique("oui") ; $numExo++ ; # Soulignés et encadrés
00046
00047 ## -------------------------------------------------------------------------------------------
00048
00049 blockquote() ;
00050
00051 blockquote() ;
00052
00053 p("texte") ;
00054 echo "$R affiche les informations en mode texte et ce n'est pas toujours facile de trouver \n" ;
00055 echo "rapidement ce que l'on cherche dans les résultats d'exécution. Ecrire une fonction \n" ;
00056 echo "nommée ".b("souligne()")." qui souligne un texte passé en paramètre avec le symbole égal par défaut \n" ;
00057 echo "comme caractère de soulignement, ou avec un autre caractère passé en deuxième paramètre. \n" ;
00058 finp() ;
00059
00060 p("texte") ;
00061 echo "Serait-ce beaucoup plus difficile de réaliser un encadrement ? \n" ;
00062 finp() ;
00063
00064 p("texte") ;
00065 echo "Voici des exemples d'exécution pour illustrer ce qu'on voudrait réaliser. \n" ;
00066 finp() ;
00067
00068 pre_fichier("souligne01.txt","cadre") ;
00069
00070 finblockquote() ;
00071
00072 solution($numExo,$numSerie) ;
00073
00074 p("texte") ;
00075 echo "Pour souligner, on peut se contenter d'afficher autant de caractères \"égal\" que le texte a \n" ;
00076 echo "de caractères. Comme ".b("nchar(chaine)")." donne la longueur de la chaine, on doit donc \n" ;
00077 echo "générer tous ces caractères avec \n" ;
00078 echo "la fonction ".hrrr("rep")." \n" ;
00079 echo "puis les mettre bout à bout \n" ;
00080 echo "avec la fonction ".hrrr("paste").", soit le code suivant où le paramètre ".b("avec")." désigne le \n" ;
00081 echo "caractère de soulignement, dont ".b("=")." est la valeur par défaut : \n" ;
00082 finp() ;
00083
00084 pre_fichier("souligne01.r","cadre") ;
00085
00086 p("texte") ;
00087 echo "Pour encadrer, c'est à peine plus compliqué, puisqu'il suffit de produire le soulignement avant et après le texte \n" ;
00088 echo "et de rajouter un symbole en début et en fin de ligne. Comme nous utilisons deux fois les mêmes informations, \n" ;
00089 echo "nous avons créé deux variables, ".b("ligneVide")." et ".b("lignePleine")." pour que ce soit plus facile à maintenir : \n" ;
00090 echo " \n" ;
00091 finp() ;
00092
00093 pre_fichier("souligne02.r","cadre") ;
00094
00095 finsolution() ;
00096
00097 finblockquote() ;
00098
00099 ## -------------------------------------------------------------------------------------------
00100
00101 $tdmCRLM->afficheRubrique("oui") ; $numExo++ ; # Utilisation de sink() et source()
00102
00103 ## -------------------------------------------------------------------------------------------
00104
00105 blockquote() ;
00106
00107 blockquote() ;
00108
00109 p("texte") ;
00110 echo "Comment fait-on pour exécuter du code $R en mode session, avec $rstudio ou en ligne de commandes ".em("shell")." ?" ;
00111 echo " Quelles sont les options d'exécution ?" ;
00112 echo " Comment obtenir un fichier ".em('"log"')." qui contient une copie dans un fichier texte de tout ce qui " ;
00113 echo " a été affiché ?" ;
00114 finp() ;
00115
00116 p("texte") ;
00117 echo "Après avoir lu l'aide sur les fonctions " ;
00118 echo hrrr("sink") ;
00119 echo " et " ;
00120 echo hrrr("source").", expliquer ce que réalise la fonction ".b("sinksource()")." suivante et " ;
00121 echo " comment on s'en sert :" ;
00122 finp() ;
00123
00124 pre_fichier("sinksource01.r","cadre") ;
00125
00126 finblockquote() ;
00127
00128 solution($numExo,$numSerie) ;
00129
00130 p("texte") ;
00131 echo "En mode session, on peut " ;
00132 finp() ;
00133
00134 ul() ;
00135
00136 debutli() ; p() ;
00137 echo "saisir au clavier les instructions, " ;
00138 finp() ; finli() ;
00139
00140 debutli() ; p() ;
00141 echo "copier/coller des instructions venus d'un éditeur ou d'une page web," ;
00142 finp() ; finli() ;
00143
00144 debutli() ; p() ;
00145 echo "exécuter les instructions d'un fichier avec ".hrrr("source").". " ;
00146 finp() ; finli() ;
00147
00148 finul() ;
00149
00150 p("texte") ;
00151 echo "Avec $rstudio, on peut de plus exécuter le code du panneau ".b("Source")."." ;
00152 finp() ;
00153
00154 p("texte") ;
00155 echo "En ligne de commandes ".em("shell")." on peut soit exécuter une expression avec l'option ".bleu("-e") ;
00156 echo " soit exécuter les instructions d'un fichier avec l'option ".bleu("-f")."." ;
00157 finp() ;
00158
00159 p("texte") ;
00160 echo " Parmi les nombreux paramètres de ".hrrr("source").", les paramètres " ;
00161 echo b("echo").", " ;
00162 echo b("print.eval")." et " ;
00163 echo b("verbose")." permettent de gérer l'affichage. Ainsi, avec ".b("echo=TRUE").", $R affiche chaque instruction avant de l'exécuter. " ;
00164 echo "Avec ".b("print.eval=TRUE")." $R affiche chaque valeur calculée par affectation. " ;
00165 echo " Voir cela en action dans notre ".href("../../Introduction_R/intror2.php?solutions=1#tdm1","séance 2") ;
00166 echo " d'".href("../../Introduction_R/","introduction à $R","grouge nou").". " ;
00167 finp() ;
00168
00169 p("texte") ;
00170 echo "La lecture du texte d'aide de la fonction ".hrrr("sink")." explique que cette fonction permet de rediriger l'affichage vers un fichier. " ;
00171 echo " Avec le paramètre ".b("split=TRUE")." l'affichage est à la fois redirigé vers l'écran et le fichier." ;
00172 finp() ;
00173
00174 p("texte") ;
00175 echo " Comme son nom l'indique, la fonction ".b("sinksource()")." réalise " ;
00176 echo " un ".hrrr("sink")." puis un ".hrrr("source").". Elle vient ensuite fermer le fichier-sink. " ;
00177 echo " Dans la mesure où le nom du fichier résultat est construit à partir du nom du fichier programme, chaque programme source " ;
00178 echo " dispose de son fichier ".em('"log"').". " ;
00179 echo " Par exemple, si on exécute ".b('sinksource("test28")')." alors $R exécute le fichier ".b("test28.r")." et " ;
00180 echo " tout ce qui est affiché à l'écran est automatiquement recopié dans le fichier ".b("test28_log.txt").". " ;
00181 echo " L'ellipse est mise dans l'entête de la fonction pour qu'on puisse passer éventuellement des options " ;
00182 echo " comme ".b("echo=TRUE").". On n'est pas obligé d'écrire ".b(".r")." à la fin du nom du fichier parce que la fonction " ;
00183 echo " détecte la présence ou l'absence de ".b(".r")." en fin de nom de fichier fourni et rajoute ".b(".r")." s'il le faut." ;
00184
00185 finp() ;
00186
00187 finsolution() ;
00188
00189 finblockquote() ;
00190
00191 ## -------------------------------------------------------------------------------------------
00192
00193 $tdmCRLM->afficheRubrique("oui") ; $numExo++ ; # Une fonction pour attendre
00194
00195 ## -------------------------------------------------------------------------------------------
00196
00197 blockquote() ;
00198
00199 blockquote() ;
00200
00201 p("texte") ;
00202 echo "On a de temps en temps besoin non pas d'interrompre mais de suspendre l'exécution et surtout l'affichage d'un " ;
00203 echo " programme, par exemple pour vérifier que les sorties correspondent à ce qu'on attendait. Ecrire une fonction " ;
00204 echo b("attendre")." qui suspend le script, pose une question et continue le script si on appuie juste sur \"Entrée\"" ;
00205 echo " ou qui quitte le programme si on écrit quelque chose." ;
00206 finp() ;
00207
00208 finblockquote() ;
00209
00210 solution($numExo,$numSerie) ;
00211
00212 p("texte") ;
00213 echo "Voici une solution possible. On lit au clavier avec " ;
00214 echo lafonction("readline")." et on arrête le script avec ".hrrr("stop")." :" ;
00215 finp() ;
00216
00217 pre_fichier("attendre.txt","cadre") ;
00218
00219 finsolution() ;
00220
00221 finblockquote() ;
00222
00223 ## -------------------------------------------------------------------------------------------
00224
00225 $tdmCRLM->afficheRubrique("oui") ; $numExo++ ; # Reproduire lafonction("ifelse")
00226
00227 ## -------------------------------------------------------------------------------------------
00228
00229 blockquote() ;
00230
00231 blockquote() ;
00232
00233 p("texte") ;
00234 echo "Afin de comprendre ce que fait la fonction $R " ;
00235 echo " nommée ".hrrr("ifelse").", écrire une fonction ".b("sialors")." qui utilise trois paramètres, " ;
00236 echo b("condition").", ".b("sioui").", ".b("sinon")." et dont le comportement est le suivant :" ;
00237 finp() ;
00238
00239 pre_fichier("s5e1.txt","cadre") ;
00240
00241 p("texte") ;
00242 echo "On rajoutera un test sur les paramètres : ainsi ".b("sialors()")." sans paramètre devra " ;
00243 echo " afficher une aide avec le rappel de la syntaxe et des exemples, comme par exemple :" ;
00244 finp() ;
00245
00246 pre_fichier("s5e2.txt","cadre") ;
00247
00248 p("texte") ;
00249 echo "Peut-on consulter le code de la fonction ".hrrr("ifelse")." ?" ;
00250 finp() ;
00251
00252 finblockquote() ;
00253
00254 solution($numExo,$numSerie) ;
00255
00256 p("texte") ;
00257 echo "Comme dit précédemment, il vaut mieux éviter les boucles, d'où une solution par filtrage vectoriel :" ;
00258 finp() ;
00259
00260 pre_fichier("sialors.r","cadre") ;
00261
00262 p("texte") ;
00263 echo "Pour consulter le code source de ".lafonction("ifelse")."il suffit de taper son nom, sans les parenthèses :" ;
00264 finp() ;
00265
00266 pre_fichier("ifelse.sor","cadre") ;
00267
00268 finsolution() ;
00269
00270 finblockquote() ;
00271
00272 ## -------------------------------------------------------------------------------------------
00273
00274 $tdmCRLM->afficheRubrique("oui") ; $numExo++ ; # Une fonction anonyme pour gérer les NA ?
00275
00276 ## -------------------------------------------------------------------------------------------
00277
00278 blockquote() ;
00279
00280 blockquote() ;
00281
00282 p("texte") ;
00283 echo "On voudrait calculer les moyennes des colonnes d'un data frame sachant qu'il y a des valeurs NA, comme par " ;
00284 echo " exemple pour les données des colonnes 2 à 4 du fichier ".bleu(href("diabete.dar")).". Montrer que l'utilisation d'une fonction anonyme suffit. " ;
00285 echo " Peut-on s'en passer ? ";
00286 finp() ;
00287
00288 finblockquote() ;
00289
00290 solution($numExo,$numSerie) ;
00291
00292 p("texte") ;
00293 echo "Effectivement faire un ".hrrr("lapply","","apply()")." de ".lafonction("mean")." ne renvoie pas le résultat attendu. " ;
00294 echo " Du coup, écrire une fonction anonyme à la volée est tentant :" ;
00295 finp() ;
00296
00297 entree_R("diabete1.r") ;
00298 sortie_R("diabete1.res") ;
00299
00300
00301 p("texte") ;
00302 echo "Mais ce serait méconnaitre R : sapply est capable de prendre des paramètres supplémentaires. " ;
00303 echo " De plus, $R dispose déjà d'une fonction pour ce calcul très classique, c'est la fonction " ;
00304 echo hrrr("colSums","","colMeans()")." :" ;
00305 finp() ;
00306
00307 entree_R("diabete2.r") ;
00308 sortie_R("diabete2.res") ;
00309
00310 finsolution() ;
00311
00312 finblockquote() ;
00313
00314 ## -------------------------------------------------------------------------------------------
00315
00316 $tdmCRLM->afficheRubrique("oui") ; $numExo++ ; # Formater l'affichage d'un data frame"
00317
00318 ## -------------------------------------------------------------------------------------------
00319
00320 blockquote() ;
00321
00322 blockquote() ;
00323
00324 p("texte") ;
00325 echo "$R sait assez bien formater une matrice de résultats numériques parce que toutes les colonnes sont numériques. " ;
00326 echo " Afficher \"proprement\" (avec un format particulier pour chaque colonne) un data.frame n'est vraiment prévu " ;
00327 echo " en $R. Implémenter une fonction ".b("printdf")." qui prend en entrée deux paramètres ".b("df")." et ".b("fmt").". " ;
00328 echo b("df")." est bien sûr un data frame et ".b("fmt")." le format de chaque colonne au sens de ".hrrr("sprintf").". " ;
00329 finp() ;
00330
00331
00332 p("texte") ;
00333 echo "Voici ce qu'on veut obtenir par exemple :" ;
00334 finp() ;
00335
00336 pre_fichier("printdf_xmp.txt","cadre") ;
00337
00338 finblockquote() ;
00339
00340 solution($numExo,$numSerie) ;
00341
00342 p("texte") ;
00343 echo "Puisque $R est ".rouge("vectoriel").", la réponse tient en une ligne : il suffit d'utiliser ".hrrr("lapply","","sapply()").". " ;
00344 finp() ;
00345
00346 pre_fichier("printdf.r","cadrebleu") ;
00347
00348
00349 p("texte") ;
00350 echo "Voici des exemples d'utilisation :" ;
00351 finp() ;
00352
00353 pre_fichier("printdf.lst","cadrejaune") ;
00354
00355
00356 p("texte") ;
00357 echo b("Explications :") ;
00358 finp() ;
00359
00360 p("texte") ;
00361 echo "Pour trouver cette solution, on peut commencer par essayer de résoudre le problème d'appliquer " ;
00362 echo " le i-ème format à la i-ème colonne du data frame. C'est très simple puisque " ;
00363 echo lafonction("sprintf")." est ".rouge("vectorielle").". " ;
00364 echo " On écrit donc ".b("sprintf(fmt[i],df[,i])").". " ;
00365 echo " Ensuite, il faut appliquer cela à toutes les colonnes. Une solution avec une boucle POUR sur i est " ;
00366 echo " possible, bien sûr mais nous savons qu'il vaut mieux éviter les boucles POUR. Il reste donc " ;
00367 echo " la solution avec ".hrrr("lapply","","sapply()").". " ;
00368 finp() ;
00369
00370 p("texte") ;
00371 echo "Comme ".lafonction("lapply","","sapply()")." applique une fonction, il faut inventer celle qui à partir de i, fmt et df " ;
00372 echo " applique sprintf(fmt[i]) à la colonne i de df. On peut écrire une fonction nommée, par exemple ".b("formatCol") ;
00373 echo " soit localement soit globalement :" ;
00374 finp() ;
00375
00376 pre_fichier("formatcol.txt","cadre") ;
00377
00378 p("texte") ;
00379 echo "Une autre solution consiste à définir une fonction anonyme directement à la suite de ".b("FUN=") ;
00380 echo " dans l'appel de ".b("sapply").". C'est la solution que nous avons choisie car ".b("formatCol") ;
00381 echo " présente peu d'intérêt en dehors de ".b("printdf").". " ;
00382 finp() ;
00383
00384 p("texte") ;
00385 echo " La notion récente (2016) de ".em("tibble")." se veut un remplacement \"propre\" (".em("tidy")." en anglais) " ;
00386 echo " des data.frame, notamment pour ces problèmes de format d'affichage. On lira avec intérêt le document en français " ;
00387 echo href("https://juba.github.io/tidyverse/06-tidyverse.html","R et tidyverse")." de J. BARNIER que nous remercions au passage pour ce document." ;
00388 finp() ;
00389
00390 finsolution() ;
00391
00392 finblockquote() ;
00393
00394 ## -------------------------------------------------------------------------------------------
00395
00396 $tdmCRLM->afficheRubrique("oui") ; $numExo++ ; # Bien afficher par() et options()
00397
00398 ## -------------------------------------------------------------------------------------------
00399
00400 blockquote() ;
00401
00402 blockquote() ;
00403
00404 p("texte") ;
00405 echo " La commande " ;
00406 echo hrrr("par","graphics") ;
00407 echo " donne, avec un affichage peu agréable, tous les paramètres graphiques. Ecrire une fonction " ;
00408 echo s_span("parPrint()","grouge")." qui les affiche par ordre alphabétique et dont voici un exemple d'affichage (tronqué) : " ;
00409 finp() ;
00410
00411 sortie_R("par1.txt") ;
00412
00413 p("texte") ;
00414 echo " Utilisez la même stratégie pour la commande " ;
00415 echo hrrr("options") ;
00416 echo " ; on écrira une fonction " ;
00417 echo s_span("optionsPrint()","grouge")." qui pourra trier par type d'information fournie ; " ;
00418 echo " en voici deux exemples d'affichage (tronqué) : " ;
00419 finp() ;
00420
00421 sortie_R("options1.txt") ;
00422
00423 finblockquote() ;
00424
00425 solution($numExo,$numSerie) ;
00426
00427 p("texte") ;
00428 echo " Voici une implémentation d'une fonction pour visualiser tous les paramètres graphiques et son affichage complet :" ;
00429 finp() ;
00430
00431 entree_R("par.r") ;
00432
00433 sortie_R("par2.txt") ;
00434
00435 p("texte") ;
00436 echo "Comme code d'une fonction qui affiche toutes les options de la configuration de R, nous vous proposons " ;
00437 finp() ;
00438
00439 # ??? expliquer ce qu'on met comme option
00440
00441 entree_R("options.r") ;
00442
00443 sortie_R("options2.txt") ;
00444
00445 finsolution() ;
00446
00447 finblockquote() ;
00448
00449 ## -------------------------------------------------------------------------------------------
00450
00451 finPageExercices($numSerie) ; # contient finSection() et finPage() ; la fonction est dans progi.php
00452
00453 ?>
Pour ne pas voir les numéros de ligne, ajoutez &nl=non à la suite du nom du fichier.
Retour à la page principale de (gH)