-
Notifications
You must be signed in to change notification settings - Fork 0
/
01-priseenmainR.qmd
1947 lines (1349 loc) · 102 KB
/
01-priseenmainR.qmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
# Prise en main de R {#sec-chap01}
Dans ce chapitre, nous revenons brièvement sur l’histoire de R et la philosophie qui entoure le logiciel. Nous donnons quelques conseils pour son installation et la mise en place d’un environnement de développement. Nous présentons les principaux objets qui sous-tendent le travail effectué avec R (*DataFrame*, vecteur, matrice, etc.) et comment les manipuler avec des exemples appliqués. Si vous maîtrisez déjà R, nullement besoin de lire ce chapitre!
::: bloc_package
::: bloc_package-header
::: bloc_package-icon
:::
**Liste des *packages* utilisés dans ce chapitre**
:::
::: bloc_package-body
* Pour importer des fichiers externes :
- `foreign` pour entre autres les fichiers *dbase* et ceux des logiciels SPSS et Stata.
- `sas7bdat` pour les fichiers du logiciel SAS.
- `xlsx` pour les fichiers Excel.
* Pour manipuler des chaînes de caractères et des dates :
- `stringr` pour les chaînes de caractères.
- `lubridate` pour les dates.
* Pour manipuler des données :
- `dplyr` du `tidyverse` propose une grammaire pour manipuler et structurer des données.
:::
:::
## Histoire et philosophie de R{#sec-011}
R est à la fois un langage de programmation et un logiciel libre (sous la licence publique générale GNU) dédié à l'analyse statistique et soutenu par une fondation : _R Foundation for Statistical Computing_. Il est principalement écrit en C et en Fortran, deux langages de programmation de « bas niveau », proches du langage machine. À l'inverse, R est un langage de « haut niveau », car plus proche du langage humain.
R a été créé par Ross Ihaka et Robert Gentleman à l'Université d'Auckland en Nouvelle-Zélande. Si vous avez un jour l'occasion de passer dans le coin, une plaque est affichée dans le département de statistique de l'université; ça mérite le détour (@fig-Plaque). Une version expérimentale a été publiée en 1996, mais la première version stable ne date que de 2000. Il s'agit donc d'un logiciel relativement récent si nous le comparons à ses concurrents SPSS (1968), SAS (1976) et Stata (1984).
![Lieu de pèlerinage de R](images/Chap01/plaque.jpg){#fig-Plaque width="40%" fig-align="center"}
R a cependant réussi à s'imposer tant dans le milieu de la recherche que dans le secteur privé. Pour s'en convaincre, il suffit de lire l'excellent article concernant la popularité des logiciels d'analyse de données tiré du site [r4stats.com](http://r4stats.com/articles/popularity){target="_blank"} (@fig-ArticlesR).
![Nombre d'articles trouvés sur Google Scholar (source : Robert A. Muenchen)](images/Chap01/r_citations.jpg){#fig-ArticlesR width="50%" fig-align="center"}
Les nombreux atouts de R justifient largement sa popularité sans cesse croissante :
* R est un logiciel à code source ouvert (*open source*) et ainsi accessible à tous gratuitement.
* Le développement du langage R est centralisé, mais la communauté peut créer et partager facilement des *packages*. Les nouvelles méthodes sont ainsi rapidement implémentées comparativement aux logiciels propriétaires.
* R est un logiciel multiplateforme, fonctionnant sur Linux, Unix, Windows et Mac.
* Comparativement à ses concurrents, R dispose d'excellentes solutions pour manipuler des données et réaliser des graphiques.
* R dispose de nombreuses interfaces lui permettant de communiquer, notamment avec des systèmes de bases de données SQL et non SQL (MySQL, PostgresSQL, MongoDB, etc.), avec des systèmes de *big data* (Spark, Hadoop), avec des systèmes d'information géographique (QGIS, ArcGIS) et même avec des services en ligne comme Microsoft Azure ou Amazon AWS.
* R est un langage de programmation à part entière, ce qui lui donne plus de flexibilité que ses concurrents commerciaux (SPSS, SAS, STATA). Avec R, vous pouvez accomplir de nombreuses tâches : monter un site web, créer un robot collectant des données en ligne, combiner des fichiers PDF, composer des diapositives pour une présentation ou même éditer un livre (comme celui-ci), mais aussi, et surtout, réaliser des analyses statistiques.
Un des principaux attraits de R est la quantité astronomique de *packages* actuellement disponibles. **Un *package* est un ensemble de nouvelles fonctionnalités développées par des personnes utilisatrices de R et mises à disposition de l'ensemble de la communauté**. Par exemple, le *package* `ggplot2` est dédié à la réalisation de graphiques; les *packages* `data.table` et `dplyr` permettent de manipuler des tableaux de données; le *package* `car` offre de nombreux outils pour faciliter l'analyse de modèles de régressions, etc. Ce partage de *packages* rend accessible à tous des méthodes d'analyses complexes et récentes et favorise grandement la reproductibilité de la recherche. Cependant, ce fonctionnement implique quelques désavantages :
* Il existe généralement plusieurs *packages* pour effectuer le même type d'analyse, ce qui peut devenir une source de confusion.
* Certains *packages* cessent d'être mis à jour au fil des années, ce qui nécessite de trouver des solutions de rechange (et ainsi apprendre la syntaxe de nouveaux *packages*).
* Il est impératif de s'assurer de la fiabilité des *packages* que vous souhaitez utiliser, car n'importe qui peut proposer un *package*.
Il nous semble important de relativiser d'emblée la portée du dernier point. Il est rarement nécessaire de lire et d'analyser le code source d'un *package* pour s'assurer de sa fiabilité. Nous ne sommes pas des spécialistes de tous les sujets et il peut être extrêmement ardu de comprendre la logique d'un code écrit par une autre personne. Nous vous recommandons donc de privilégier l'utilisation de *packages* qui :
* ont fait l'objet d'une publication dans une revue à comité de lecture ou qui ont déjà été cités dans des études ayant fait l'objet d'une publication revue par les pairs;
* font partie de projets comme [ROpensci](https://ropensci.org/){target="_blank"} prônant la vérification par les pairs ou subventionnés par des organisations comme [R Consortium](https://www.r-consortium.org/){target="_blank"};
* sont disponibles sur l'un des deux principaux répertoires de *packages* R, soit [CRAN](https://cran.r-project.org/){target="_blank"} et [Bioconductor](https://www.bioconductor.org/){target="_blank"}.
Toujours pour nuancer notre propos, il convient de distinguer *package* de *package*! Certains d'entre eux sont des ensembles très complexes de fonctions permettant de réaliser des analyses poussées alors que d'autres sont des projets plus modestes dont l'objectif principal est de simplifier le travail des personnes utilisant R. Ces derniers ressemblent à de petites boîtes à outils et font généralement moins l'objet d'une vérification intensive.
Pour conclure cette section, l'illustration partagée sur Twitter par Darren L Dahly résume avec humour la force du logiciel R et de sa communauté
(@fig-fig03) : R apparaît clairement comme une communauté hétéroclite, mais diversifiée et adaptable.
![Métaphore sur les langages et programmes d'analyse statistique](images/Chap01/softwares_and_cars.jpeg){#fig-fig03 width="60%" fig-align="center"}
Dans ce livre, nous détaillons les *packages* utilisés dans chaque section avec un encadré spécifique.
::: bloc_package
::: bloc_package-header
::: bloc_package-icon
:::
**Bloc *packages***
:::
::: bloc_package-body
Habituellement localisé au début d'un chapitre, il comprend la liste des *packages* R utilisés pour un chapitre.
:::
:::
## Environnement de travail{#sec-012}
Dans cette section, nous vous proposons une visite de l'environnement de travail de R.
### Installation de R {#sec-0121}
La première étape pour travailler avec R est bien sûr de l'installer. Pour cela, il suffit de visiter le site web de [CRAN](https://cran.r-project.org/){target="_blank"} et de télécharger la dernière version de R en fonction de votre système d'exploitation : Windows, Linux ou Mac. Une fois installé, si vous démarrez R immédiatement, vous aurez accès à une console, plutôt rudimentaire, attendant sagement vos instructions (@fig-fig05).
![Console de base de R](images/Chap01/r_console.jpeg){#fig-fig05 width="85%" fig-align="center"}
Notez que vous pouvez aussi télécharger des versions plus anciennes de R en allant sur ce [lien](https://cran.r-project.org/bin/windows/base/old/){target="_blank"}. Cela peut être intéressant lorsque vous voulez reproduire des résultats d'une autre étude ou que certains *packages* ne sont plus disponibles dans les nouvelles versions.
### Environnement RStudio{#sec-0122}
Rares sont les adeptes de R qui préfèrent travailler directement avec la console classique. Nous vous recommandons vivement d'utiliser RStudio, un environnement de développement (*IDE*) dédié à R offrant une intégration très intéressante d'une console, d'un éditeur de texte, d'une fenêtre de visualisation des données et d'une autre pour les graphiques, d'un accès à la documentation, etc. En d'autres termes, si R est un vélo minimaliste, RStudio permet d'y rajouter des freins, des vitesses, un porte-bagages, des garde-boues et une selle confortable. Vous pouvez [télécharger](https://rstudio.com/products/rstudio/download){target="_blank"} et installer RStudio sur Windows, Linux et Mac. La version de base est gratuite, mais l'entreprise qui développe ce logiciel propose aussi des versions commerciales du logiciel qui assurent essentiellement une assistance technique. Il existe d'autres environnements de développement pour travailler avec R (Visual Studio Code, Jupyter, Tinn-R, Radiant, RIDE, etc.), mais RStudio offre à ce jour la meilleure option en termes de facilité d'installation, de prise en main et de fonctionnalités proposées (voir l'interface de RStudio à la @fig-fig06).
![Environnement de base de RStudio](images/Chap01/r_studio_01.jpeg){#fig-fig06 width="85%" fig-align="center"}
Avant d'aller plus loin, notez que :
* La console actuellement ouverte dans RStudio vous informe de la version de R que vous utilisez. Vous pouvez en effet avoir plusieurs versions de R installées sur votre ordinateur et passer de l'une à l'autre avec RStudio. Pour cela, naviguez dans l'onglet *Tools/Global Options* et dans le volet *General*, puis sélectionnez la version de R que vous souhaitez utiliser.
* L'aspect de RStudio peut être modifié en naviguant dans l'onglet *Tools/Global Options* et dans le volet *Appearance*. Nous avons une préférence pour le mode sombre avec le style *pastel on dark* (@fig-fig07), mais libre à vous de choisir le style qui vous convient.
![RStudio avec le style pastel on dark](images/Chap01/r_studio_02.jpeg){#fig-fig07 width="85%" fig-align="center"}
Une fois ces détails réglés, vous pouvez ouvrir votre première feuille de code en allant dans l'onglet *File/New File/R Script*. Votre environnement est maintenant découpé en quatre fenêtres (@fig-fig08) :
1. L'éditeur de code, vous permettant d'écrire le script que vous voulez exécuter et de garder une trace de votre travail. Ce script peut être enregistré sur votre ordinateur avec l'extension **.R**, mais ce n'est qu'un simple fichier texte.
2. La console vous permettant d'exécuter votre code R et de voir les résultats s'afficher au fur et à mesure.
3. La fenêtre d'environnement vous montrant les objets, les fonctions et les jeux de données actuellement disponibles dans votre session (chargés dans la mémoire vive).
4. La fenêtre de l'aide, des graphiques et de l'explorateur de fichiers. Vous pouvez accéder ici à la documentation de R et des *packages* que vous utilisez, aux sorties graphiques que vous produisez et aux dossiers de votre environnement de travail.
![Fenêtres de RStudio](images/Chap01/r_studio_03.jpeg){#fig-fig08 width="85%" fig-align="center"}
Prenons un bref exemple : tapez la syntaxe suivante dans l'éditeur de code (fenêtre 1 à la @fig-fig08) :
```{r}
#| label: "ma_somme"
ma_somme <- 4+4
```
Sélectionnez ensuite cette syntaxe (mettre en surbrillance avec la souris) et utilisez le raccourci *Ctrl+Entrée* ou cliquez sur le bouton *Run* (avec la flèche verte) pour envoyer cette syntaxe à la console qui l'exécutera immédiatement. Notez que rien ne se passe tant que le code n'est pas envoyé à la console. Il s'agit donc de deux étapes distinctes : écrire son code, puis l'envoyer à la console. Constatez également qu'un objet *ma_somme* est apparu dans votre environnement et que sa valeur est bien 8. Votre console se « souvient » de cette valeur : elle est actuellement stockée dans votre mémoire vive sous le nom de *ma_somme* (@fig-fig09).
![Exécuter du code dans RStudio](images/Chap01/r_studio_04.jpeg){#fig-fig09 width="85%" fig-align="center"}
Pour conclure cette section, nous vous invitons à enregistrer votre première syntaxe R (*File/Save As*) dans un fichier **.R** que vous pouvez appeler `mon_premier_script.R` par exemple. Fermez ensuite RStudio, redémarrez-le et ouvrez (*File/Open File*) votre fichier `mon_premier_script.R`. Vous pouvez constater que votre code est toujours présent, mais que votre environnement est vide tant que vous n'exécutez pas votre syntaxe. En effet, lorsque vous fermez RStudio, l'environnement est vidé pour libérer de la mémoire vive. Cela peut poser problème lorsque certains codes sont très longs à exécuter, nous verrons donc plus tard comment enregistrer l'environnement en cours pour le recharger par la suite.
### Installation et chargement un *package*{#sec-0123}
Dans la section sur la Philosophie de R, nous avons souligné la place centrale jouée par les *packages*. Notez que les termes *paquet* et plus rarement *librairie* sont parfois utilisés en français. Voyons ensemble comment installer un *package*, par exemple celui intitulé `lubridate`, qui nous permettra plus tard de manipuler des données temporelles.
#### Installation d'un *package* depuis *CRAN*{#sec-01231}
Pour installer un *package*, il est nécessaire d'être connecté à Internet puisque R va accéder au répertoire de *packages* *CRAN* pour télécharger le *package* et l'installer sur votre machine. Cette opération est réalisée avec la fonction `install.packages`.
```{r}
#| message: false
#| warning: false
#| eval: false
install.packages("lubridate")
```
Notez qu'une fois que le *package* est installé, il demeure disponible localement sur votre ordinateur, à moins de le désinstaller explicitement avec la fonction `remove.packages`.
#### Installation d'un *package* depuis GitHub{#sec-01232}
*CRAN* est le répertoire officiel des *packages* de R. Vous pouvez cependant télécharger des *packages* provenant d'autres sources. Très souvent, les *packages* sont disponibles sur le site web [GitHub](https://github.com/){target="_blank"} et nous pouvons même y trouver des versions en développement avec des fonctionnalités encore non intégrées dans la version sur *CRAN*. Reprenons le cas de `lubridate`, mais sur GitHub (il est disponible [ici](https://github.com/tidyverse/lubridate){target="_blank"}). Pour l'installer, nous devons d'abord installer un autre *package* appelé `remotes` (depuis *CRAN*).
```{r}
#| message: false
#| warning: false
#| eval: false
install.packages("remotes")
```
Maintenant que nous disposons de `remotes`, nous pouvons utiliser la fonction d'installation `remotes::install_github` pour directement télécharger `lubridate` depuis GitHub.
```{r}
#| message: false
#| warning: false
#| eval: false
remotes::install_github("tidyverse/lubridate")
```
#### Chargement d'un *package* {#sec-01233}
Maintenant que `lubridate` est installé, nous pouvons le charger dans notre session actuelle de R et accéder aux fonctions qu'il propose. Pour cela, il suffit d'utiliser la fonction `library`. Conventionnellement, l'appel des *packages* se fait au tout début du script que vous rédigez. Rien ne vous empêche de le faire au fur et à mesure de votre code, mais ce dernier perd alors en lisibilité. Notez que pour chaque nouvelle session (redémarrage de R), il faut recharger les *packages* dont vous avez besoin avec la fonction `library`.
```{r}
#| message: false
#| warning: false
library(lubridate)
```
Si vous obtenez un message d'erreur du type :
`Error in library(monPackage) : aucun package nommé ‘monPackage’ n'est trouvé`
Cela signifie que le *package* que vous tentez de charger n'est pas encore installé sur votre ordinateur. Dans ce cas, réessayer de l'installer avec la fonction `install.packages`. Si le problème persiste, vérifiez que vous n'avez pas fait une faute de frappe dans le nom du *package.* Vous pouvez également redémarrer RStudio et réessayer d'installer ce *package*.
### Aide disponible
Lorsque vous installez des *packages* dans R, vous téléchargez aussi leur documentation. Tous les *packages* de *CRAN* disposent d'une documentation, ce qui n'est pas forcément vrai pour ceux sur *GitHub*. Dans RStudio, vous pouvez accéder à la documentation des *packages* dans l'onglet **Packages** (@fig-fig010). Vous pouvez utiliser la barre de recherche pour retrouver rapidement un *package* installé. Si vous cliquez sur le nom du *package*, vous accédez directement à sa documentation dans cette fenêtre.
![Description des packages](images/Chap01/rstudio_packages.jpeg){#fig-fig010 width="45%" fig-align="center"}
Vous pouvez également accéder à ces informations en utilisant la syntaxe suivante dans votre console :
```{r}
#| eval: false
help(package = 'lubridate')
```
Souvent, vous aurez besoin d'accéder à la documentation d'une fonction spécifique d'un *package*. Affichons la documentation de la fonction `now` de `lubridate` :
```{r}
#| eval: false
help(now, package = 'lubridate')
```
ou plus simplement :
```{r}
#| eval: false
?lubridate::now
```
Vous pouvez aussi utiliser le raccourci suivant.
```{r}
#| eval: false
?now
```
Si vous ne vous souvenez plus à quel *package* la fonction appartient, lancez une recherche en utilisant un double point d'interrogation :
```{r}
#| eval: false
??now
```
Vous découvrirez ainsi que la fonction `now` n'existe pas que dans `lubridate`, ce qui souligne l'importance de bien connaître les *packages* que nous installons et que nous chargeons dans notre session !
Maintenant que nous avons fait le tour de l'environnement de travail, nous pouvons passer aux choses sérieuses, soit les bases du langage R.
## Bases du langage R {#sec-013}
R est un langage de programmation. Il vous permet de communiquer avec votre ordinateur pour lui donner des tâches à accomplir. Dans cette section, nous abordons les bases du langage. Ce type de section introductive à R est présente dans tous les manuels sur R; elle est donc incontournable. À la première lecture, elle vous semblera probablement aride, et ce, d'autant plus que nous ne réalisons pas d'analyse à proprement parler. Gardez en tête que l'analyse de données requiert au préalable une phase de structuration de ces dernières, opération qui nécessite la maîtrise des notions abordées dans cette section. Nous vous recommandons une première lecture de ce chapitre pour comprendre les manipulations que vous pouvez effectuer avec R, avant de poursuivre avec de la lecture des chapitres suivants dédiés aux analyses statistiques. Vous pourrez revenir consulter cette section au besoin. Notez aussi que la maîtrise des différents objets et des différentes opérations de base de R ne s’acquiert qu'en pratiquant. Vous gagnerez cette expertise au fil de vos prochains codes R, période durant laquelle vous pourrez consulter ce chapitre tel un guide de référence des objets et des notions fondamentales de R.
### *Hello World*! {#sec-0131}
Une introduction à un langage de programmation se doit de commencer par le rite de passage *Hello World*. Il s'agit d'une forme de tradition consistant à montrer aux néophytes comment afficher le message `Hello World` à l'écran avec le langage en question.
```{r}
print("Hello World")
```
Bravo! Vous venez officiellement de faire votre premier pas dans R!
### Objets et expressions {#sec-0132}
Dans R, nous passons notre temps à manipuler des **objets** à l'aide d'**expressions**. Prenons un exemple concret : si vous tapez la syntaxe `4 + 3`, vous manipulez deux objets (4 et 3) avec une expression indiquant que vous souhaitez obtenir la somme des deux objets.
```{r}
4 + 3
```
Cette expression est correcte, R comprend vos indications et effectue le calcul.
Il est possible d'enregistrer le résultat d'une expression et de le conserver dans un nouvel objet. On appelle cette opération : « déclarer une variable ».
```{r}
ma_somme <- 4 + 3
```
Concrètement, nous venons de demander à R d'enregistrer le résultat de `4 + 3` dans un espace spécifique de notre mémoire vive. Si vous regardez dans votre fenêtre **Environment**, vous verrez en effet qu'un objet appelé ma_somme est actuellement en mémoire et a pour valeur 7.
Notez ici que le nom des variables ne peut être composé que de lettres, de chiffres, de points (.) et de tirets bas (_) et doit commencer par une lettre. R est sensible à la casse; en d'autres termes, les variables `Ma_somme`, `ma_sommE`, `ma_SOMME`, et `MA_SOMME` renvoient toutes à un objet différent. Attention donc aux fautes de frappe. Si vous déclarez une variable en utilisant le nom d'une variable existante, la première est écrasée par la seconde :
```{r}
age <- 35
age
age <- 45
age
```
Portez alors attention aux noms de variables que vous utilisez et réutilisez. Réutilisons notre objet `ma_somme` dans une nouvelle expression :
```{r}
ma_somme2 <- ma_somme + ma_somme
```
Avec cette nouvelle expression, nous indiquons à R que nous souhaitons déclarer une nouvelle variable appelée `ma_somme2`, et que cette variable aura pour valeur `ma_somme + ma_somme`, soit `7 + 7`. Sans surprise, `ma_somme2` a pour valeur 14.
Notez que la mémoire vive (l'environnement) est vidée lorsque vous fermez R. Autrement dit, R perd complètement la mémoire lorsque vous le fermez. Vous pouvez bien sûr recréer vos objets en relançant les mêmes syntaxes. C'est pourquoi vous devez conserver vos feuilles de codes et ne pas seulement travailler dans la console. La console ne garde aucune trace de votre travail. Pensez donc à bien enregistrer votre code!
Nous verrons dans une prochaine section comment sauvegarder des objets et les recharger dans une session ultérieure de R ([section @sec-017]). Ce type d'opération est pertinent quand le temps de calcul nécessaire à la production de certains objets est très long.
### Fonctions et arguments {#sec-0_133}
Dans R, nous manipulons le plus souvent nos objets avec des **fonctions**. Une fonction est elle-même un objet, mais qui a la particularité de pouvoir effectuer des opérations sur d'autres objets. Par exemple, déclarons l'objet `taille` avec une valeur de 175,897 :
```{r}
taille <- 175.897
```
Nous utilisons la fonction `round`, dont l'objectif est d'arrondir un nombre avec décimales pour obtenir un nombre entier.
```{r}
round(taille)
```
Pour effectuer leurs opérations, les fonctions ont généralement besoin d'**arguments**. Ici, `taille` est un argument passé à la fonction `round`. Si nous regardons la documentation de `round` avec `help(round)` (@fig-fig011), nous constatons que cette fonction prend en réalité deux arguments : *x* et *digits*. Le premier est le nombre que nous souhaitons arrondir et le second est le nombre de décimales à conserver. Nous pouvons lire dans la documentation que la valeur par défaut de *digits* est 0, ce qui explique que `round(taille)` a produit le résultat de 176.
![Arguments de la fonction `round`](images/Chap01/help_round.jpeg){#fig-fig011 width="35%" fig-align="center"}
Réutilisons maintenant la fonction `round`, mais en gardant une décimale :
```{r}
round(taille, digits = 1)
```
Il est aussi possible que certaines fonctions ne requièrent pas d'argument. Par exemple, la fonction `now` indique la date précise (avec l'heure) et n'a besoin d'aucun argument pour le faire :
```{r}
now()
```
Par contre, si nous essayons de lancer la fonction `round` sans argument, nous obtenons une erreur :
```{r}
#| eval: false
round()
```
`Erreur : 0 argument passé à 'round' qui en exige 1 ou 2`
Le message est très clair, `round` a besoin d'au moins un argument pour fonctionner. Si, au lieu d'un nombre, nous avions donné du texte à la fonction `round`, nous aurions aussi obtenu une erreur :
```{r}
#| eval: false
round("Hello World")
```
`Erreur dans round("Hello World") : argument non numérique pour une fonction mathématique`
À nouveau le message est très explicite : nous avons passé un argument non numérique à une fonction mathématique. Lisez toujours vos messages d'erreurs : ils permettent de repérer les coquilles et de corriger votre code!
Nous terminons cette section avec une fonction essentielle, `print`, qui permet d'afficher la valeur d'une variable.
```{r}
print(ma_somme)
```
### Principaux types de données {#sec-0134}
Depuis le début de ce chapitre, nous avons déclaré plusieurs variables et essentiellement des données numériques. Dans R, il existe trois principaux types de données de base :
* Les données numériques qui peuvent être des nombres entiers (appelés *integers*) ou des nombres décimaux (appelés *floats* ou *doubles*), par exemple `15` et `15.3`.
* Les données de type texte qui sont des chaînes de caractères (appelées *strings*) et déclarées entre guillemets `"abcdefg"`.
* Les données booléennes (*booleans*) qui peuvent n'avoir que deux valeurs : vrai (`TRUE`) ou faux (`FALSE`).
Déclarons une variable pour chacun de ces types :
```{r}
age <- 35
taille <- 175.5
adresse <- '4225 rue de la gauchetiere'
proprietaire <- TRUE
```
::: bloc_notes
::: bloc_notes-header
::: bloc_notes-icon
:::
**Simples ou doubles quotes?**
:::
::: bloc_notes-body
Pour déclarer des données de type texte, il est possible d'utiliser des quotes simples `'` (apostrophe) ou des quotes doubles `"` (guillemets), cela ne fait aucune différence pour R. Cependant, si la chaîne de caractères que vous créez contient une apostrophe, il est nécessaire d'utiliser des quotes doubles et inversement si votre chaîne de caractère contient des guillemets.
```{r}
phrase1 <- "J'adore le langage R!"
phrase2 <- 'Je cite : "il est le meilleur langage de statistique".'
```
Si la chaîne de caractère contient des guillemets et des apostrophes, il est nécessaire d'utiliser la barre oblique inversée `\` pour indiquer à R que ces apostrophes ou ces guillemets ne doivent pas être considérés comme la fin de la chaîne de caractère.
```{r}
phrase3 <- "Je cite : \"j'en rêve la nuit\"."
cat(phrase3)
```
Les barres obliques inversées ne font pas partie de la chaîne de caractère, ils sont là pour "échapper" les guillemets qui doivent rester dans la chaîne de caractère. Si une chaîne de caractère doit contenir une barre oblique inversée, alors il faut l'échapper également en utilisant une deuxième barre oblique inversée.
```{r}
phrase4 <- "Une phrase avec une barre oblique inversée : \\"
cat(phrase4)
```
Faites attention à la coloration syntaxique de RStudio! Elle peut vous aider à repérer facilement une chaîne de caractère qui aurait été interrompue par un guillemet ou une apostrophe mal placés.
:::
:::
Si vous avez un doute sur le type de données stockées dans une variable, vous pouvez utiliser la fonction `typeof`. Par exemple, cela permet de repérer si des données qui sont censées être numériques sont en fait stockées sous forme de texte comme dans l'exemple ci-dessous.
```{r}
typeof(age)
typeof(taille)
# Ici tailletxt est définie comme une chaîne de caractère car la valeur est
# définie entre des guillemets.
tailletxt <- "175.5"
typeof(tailletxt)
```
Notez également qu'il existe des types pour représenter l'absence de données :
* pour représenter un objet vide, nous utilisons l'objet `NULL`,
* pour représenter une donnée manquante, nous utilisons l'objet `NA`,
* pour représenter un texte vide, nous utilisons une chaîne de caractère de longueur 0, soit `""`.
```{r}
age2 <- NULL
taille2 <- NA
adresse2 <- ''
```
### Opérateurs {#sec-0135}
Nous avons vu que les fonctions permettent de manipuler des objets. Nous pouvons également effectuer un grand nombre d'opérations avec les opérateurs.
#### Opérateurs mathématiques {#sec-01351}
Les opérateurs mathématiques (@tbl-OperateurMath) permettent d'effectuer des calculs avec des données de type numérique.
```{r}
#| label: tbl-OperateurMath
#| tbl-cap: Opérateurs mathématiques
#| echo: false
#| message: false
#| warning: false
df <- data.frame(
Operateur = c("`+`" , "`-`" , "`*`" , "`/`", "`^`", "`**`",
"`%%`", "`%/%`"),
Description = c("Addition", 'Soustraction', 'Multiplication',
'Division', 'Exponentiel', 'Exponentiel',
'Reste de division', 'Division entière'),
Syntaxe = c("`4 + 4`", "`4 - 3`", "`4 * 3`", "`12 / 4`",
"`4 ^ 3`", '`4 ** 3`', "`15,5 %% 2`",
"`15,5 %/% 2`"),
Resultat = c(8,1,12,3,64,64,1.5,7))
knitr::kable(df,
format.args = list(decimal.mark = ',', big.mark = " "),
col.names = c("Opérateur" , "Description" , "Syntaxe" , "Résultat"),
align= c("l", "l", "l", "r")
)
```
#### Opérateurs relationnels {#sec-01352}
Les opérateurs relationnels (@tbl-OperateurRelationnels) permettent de vérifier des conditions dans R. Ils renvoient un booléen, `TRUE` si la condition est vérifiée et `FALSE` si ce n'est pas le cas.
```{r}
#| label: tbl-OperateurRelationnels
#| tbl-cap: Opérateurs relationnels
#| echo: false
#| message: false
#| warning: false
df <- data.frame(
Operateur = c("`==`" , "`!=`" , "`>`" , "`<`", "`>=`", "`<=`"),
Description = c("Égalité", 'Différence', 'Est supérieur ', 'Est inférieur', 'Est supérieur ou égal', 'Est inférieur ou égal'),
Syntaxe = c("`4 == 4`", "`4 != 4`", "`5 > 4`", "`5 < 4`", "`5 >= 4`", '`5 <= 4`'),
Resultat = c(TRUE, FALSE, TRUE, FALSE, TRUE, FALSE))
knitr::kable(df,
format.args = list(decimal.mark = ',', big.mark = " "),
col.names = c("Opérateur" , "Description" , "Syntaxe" , "Résultat"),
align= c("l", "l", "l", "l"))
```
#### Opérateurs logiques {#sec-01353}
Les opérateurs logiques (@tbl-tableOperateurLogi) permettent de combiner plusieurs conditions :
* L'opérateur **ET** (`&`) permet de vérifier que deux conditions (l'une ET l'autre) sont TRUE. Si l'une des deux est FALSE, il renvoie FALSE.
* L'opérateur **OU** (`|`) permet de vérifier que l'une des deux conditions est TRUE (l'une OU l'autre). Si les deux sont FALSE, alors il renvoie FALSE.
* L'opérateur **NOT** (`!`) permet d'inverser une condition. Ainsi, NOT TRUE donne FALSE et NOT FALSE donne TRUE.
```{r}
#| label: tbl-tableOperateurLogi
#| tbl-cap: Opérateurs logiques
#| echo: false
#| message: false
#| warning: false
df <- data.frame(
Operateur = c("`&`" , "`|`" , "`!`"),
Description = c("ET", "OU", "NOT"),
Syntaxe = c("`TRUE & FALSE`", "`TRUE | FALSE`", "`! TRUE`"),
Resultat = c(FALSE, TRUE, FALSE))
knitr::kable(df,
format.args = list(decimal.mark = ',', big.mark = " "),
col.names = c("Opérateur" , "Description" , "Syntaxe" , "Résultat"),
align= c("l", "l", "l", "l")
)
```
Prenons le temps pour un rapide exemple :
```{r}
A <- 4
B <- 10
C <- -5
# Produit TRUE car A est bien plus petit que B et C est bien plus petit que A
A < B & C < A
# Produit FALSE car si A est bien plus petit que B,
# B est en revanche plus grand que c
A < B & B < C
# Produit TRUE car la seconde condition est inversée
A < B & ! B < C
# Produit TRUE car au moins une des deux conditions est juste
A < B | B < C
```
Notez que l'opérateur **ET** est prioritaire sur l'opérateur **OU** et que les parenthèses sont prioritaires sur tous les opérateurs :
```{r}
# Produit TRUE car nous commençons par tester A < B puis B < C ce qui donne FALSE
# On obtient ensuite
# FALSE | A > C
# Enfin, A est bien supérieur à C, donc l'une des deux conditions est vraie
A < B & B < C | A > C
```
Notez qu'en arrière-plan, les opérateurs sont en réalité des fonctions déguisées. Il est donc possible de définir de nouveaux comportements pour les opérateurs. Il est par exemple possible d'additionner ou de comparer des objets spéciaux comme des dates, des géométries, des graphes, etc.
### Structures de données {#sec-0136}
Jusqu'à présent, nous avons utilisé des objets ne comprenant qu'une seule valeur. Or, des analyses statistiques nécessitent de travailler avec des volumes de données bien plus grands. Pour stocker des valeurs, nous travaillons avec différentes structures de données : les vecteurs, les matrices, les tableaux de données et les listes.
#### Vecteurs {#sec-01361}
Les vecteurs sont la brique élémentaire de R. Ils permettent de stocker une série de valeurs **du même type** dans une seule variable. Pour déclarer un vecteur, nous utilisons la fonction `c()` :
```{r}
ages <- c(35,45,72,56,62)
tailles <- c(175.5,180.3,168.2,172.8,167.6)
adresses <- c('4225 rue de la gauchetiere',
'4223 rue de la gauchetiere',
'4221 rue de la gauchetiere',
'4219 rue de la gauchetiere',
'4217 rue de la gauchetiere')
proprietaires <- c(TRUE, TRUE, FALSE, TRUE, TRUE)
```
Nous venons ainsi de déclarer quatre nouvelles variables étant chacune un vecteur de longueur cinq (comprenant chacun cinq valeurs). Ces vecteurs représentent, par exemple, les réponses de plusieurs personnes à un questionnaire.
::: bloc_attention
::: bloc_attention-header
::: bloc_attention-icon
:::
**Distinction entre un vecteur de type texte et un vecteur de type facteur**
:::
::: bloc_attention-body
Il existe dans R une subtilité à l'origine de nombreux malentendus : la distinction entre un vecteur de type **texte** et un vecteur de type **facteur**. Dans l'exemple précédent, le vecteur *adresses* est un vecteur de type texte. Chaque nouvelle valeur ajoutée dans le vecteur peut être n'importe quelle nouvelle adresse. Déclarons un nouveau vecteur qui contient cette fois-ci la couleur des yeux de personnes ayant répondu au questionnaire.
```{r}
couleurs_yeux <- c('marron', 'marron', 'bleu', 'bleu', 'marron', 'vert')
```
Contrairement aux adresses, il y a un nombre limité de couleurs que nous pouvons mettre dans ce vecteur. Il est donc intéressant de fixer les valeurs possibles du vecteur pour éviter d'en ajouter de nouvelles par erreur. Pour cela, nous devons convertir ce vecteur texte en vecteur de type facteur, ci-après nommé simplement facteur, avec la fonction `as.factor`.
```{r}
couleurs_yeux_facteur <- as.factor(couleurs_yeux)
```
Notez qu'à présent, nous pouvons ajouter une nouvelle couleur dans le premier vecteur, mais pas dans le second.
```{r}
couleurs_yeux[7] <- "rouge"
couleurs_yeux_facteur[7] <- "rouge"
```
Le message d'erreur nous informe que nous avons tenté d'introduire une valeur invalide dans le facteur.
Les facteurs peuvent sembler restrictifs et, très régulièrement, nous préférons travailler avec de simples vecteurs de type texte plutôt que des facteurs. Cependant, de nombreuses fonctions d'analyse nécessitent d'utiliser des facteurs, car ils assurent une certaine cohérence dans les données. Il est donc essentiel de savoir passer du texte au facteur avec la fonction `as.factor`. À l'inverse, il est parfois nécessaire de revenir à une variable de type texte avec la fonction `as.character`.
Notez que des vecteurs numériques peuvent aussi être convertis en facteurs :
```{r}
tailles_facteur <- as.factor(tailles)
```
Cependant, si vous souhaitez reconvertir ce facteur en format numérique, il faudra passer dans un premier temps par le format texte :
```{r}
as.numeric(tailles_facteur)
```
Comme vous pouvez le voir, convertir un facteur en valeur numérique renvoie des nombres entiers. Ceci est dû au fait que les valeurs dans un facteur sont recodées sous forme de nombres entiers, chaque nombre correspondant à une des valeurs originales (appelées niveaux). Si nous convertissons un facteur en valeurs numériques, nous obtenons donc ces nombres entiers.
```{r}
as.numeric(as.character(tailles_facteur))
```
Morale de l'histoire : ne confondez pas les données de type texte et de type facteur. Dans le doute, vous pouvez demander à R quel est le type d'un vecteur avec la fonction `class`.
```{r}
class(tailles)
class(tailles_facteur)
class(couleurs_yeux)
class(couleurs_yeux_facteur)
```
:::
:::
Quasiment toutes les fonctions utilisent des vecteurs. Par exemple, nous pouvons calculer la moyenne du vecteur *ages* en utilisant la fonction `mean` présente de base dans R.
```{r}
mean(ages)
```
Cela démontre bien que le vecteur est la brique élémentaire de R! Toutes les variables que nous avons déclarées dans les sections précédentes sont aussi des vecteurs, mais de longueur 1.
#### Matrices {#sec-01362}
Il est possible de combiner des vecteurs pour former des matrices. Une matrice est un tableau en deux dimensions (colonnes et lignes) et est généralement utilisée pour représenter certaines structures de données comme des images (pixels), effectuer du calcul matriciel ou plus simplement présenter des matrices de corrélations. Vous aurez rarement à travailler directement avec des matrices, mais il est bon de savoir ce qu'elles sont. Créons deux matrices à partir de nos précédents vecteurs.
```{r}
matrice1 <- cbind(ages, tailles)
# Afficher la matrice 1
print(matrice1)
# Afficher les dimensions de la matrice 1 (1er chiffre : lignes; 2e chiffre : colonnes)
print(dim(matrice1))
matrice2 <- rbind(ages, tailles)
# Afficher la matrice 2
print(matrice2)
# Afficher les dimensions de la matrice 2
print(dim(matrice2))
```
Comme vous pouvez le constater, la fonction `cbind` permet de concaténer des vecteurs comme s'ils étaient les colonnes d'une matrice, alors que `rbind` les combine comme s'ils étaient les lignes d'une matrice. La @fig-fig012 présente graphiquement le passage du vecteur à la matrice.
![Du vecteur à la matrice](images/Chap01/vecteur_to_matrix.png){#fig-fig012 width="30%" fig-align="center"}
Notez que vous pouvez transposer une matrice avec la fonction `t`. Si nous essayons maintenant de comparer la matrice 1 à la matrice 2 nous allons avoir une erreur, car elles n'ont pas les mêmes dimensions.
```{r}
#| eval: false
matrice1 == matrice2
```
`Erreur dans matrice1 == matrice2 : tableaux de tailles inadéquates`
En revanche, nous pouvons transposer la matrice 1 et refaire cette comparaison :
```{r}
t(matrice1) == matrice2
```
Le résultat souligne bien que nous avons les mêmes valeurs dans les deux matrices. Il est aussi possible de construire des matrices directement avec la fonction `matrix`, ce que nous montrons dans la prochaine section.
#### *Arrays* {#sec-01363}
S'il est rare de travailler avec des matrices, il est encore plus rare de manipuler des *arrays*. Un *array* est une matrice spéciale qui peut avoir plus que deux dimensions. Un cas simple serait un *array* en trois dimensions : lignes, colonnes, profondeur, que nous pourrions représenter comme un cube, ou une série de matrices de mêmes dimensions et empilées. Au-delà de trois dimensions, il devient difficile de les représenter mentalement. Cette structure de données peut être utilisée pour représenter les différentes bandes spectrales d'une image satellitaire. Les lignes et les colonnes délimiteraient les pixels de l'image et la profondeur délimiterait les différentes bandes composant l'image (@fig-fig012).
![Un array avec trois dimensions](images/Chap01/array.png){#fig-fig013 width="15%" fig-align="center"}
Créons un *array* en combinant trois matrices avec la fonction `array`. Chacune de ces matrices est composée respectivement de 1, de 2 et de 3 et a une dimension de 5 x 5. L'*array* final a donc une dimension de 5 x 5 x 3.
```{r}
mat1 <- matrix(1, nrow = 5, ncol = 5)
mat2 <- matrix(2, nrow = 5, ncol = 5)
mat3 <- matrix(3, nrow = 5, ncol = 5)
mon_array <- array(c(mat1, mat2, mat3), dim = c(5,5,3))
print(mon_array)
```
#### *DataFrames* {#sec-01364}
S'il est rare de manipuler des matrices et des *arrays*, le *DataFrame* (tableau de données en français) est la structure de données la plus souvent utilisée. Dans cette structure, chaque ligne du tableau représente un individu et chaque colonne représente une caractéristique de cet individu. Ces colonnes ont des noms qui permettent facilement d'accéder à leurs valeurs. Créons un *DataFrame* (@tbl-tabfirsttable) à partir de nos quatre vecteurs et de la fonction `data.frame`.
```{r}
df <- data.frame(
"age" = ages,
"taille" = tailles,
"adresse" = adresses,
"proprietaire" = proprietaires
)
```
```{r}
#| label: tbl-tabfirsttable
#| tbl-cap: Premier DataFrame
#| echo: false
#| message: false
#| warning: false
knitr::kable(df,
format.args = list(decimal.mark = ',', big.mark = " "),
align= c("c", "c", "l", "l")
)
```
Dans RStudio, vous pouvez visualiser votre tableau de données avec la fonction `View(df)`. Comme vous pouvez le constater, chaque vecteur est devenu une colonne de votre tableau de données *df*. La @fig-fig013 résume ce passage d'une simple donnée à un *DataFrame* en passant par un vecteur.
![De la donnée au DataFrame](images/Chap01/vecteur_to_dataframe.png){#fig-fig013 width="25%" fig-align="center"}
Plusieurs fonctions de base de R fournissent des informations importantes sur un *DataFrame* :
* `names` renvoie les noms des colonnes du *DataFrame*;
* `nrow` renvoie le nombre de lignes;
* `ncol` renvoie le nombre de colonnes.
```{r}
names(df)
nrow(df)
ncol(df)
```
Vous pouvez accéder à chaque colonne de *df* en utilisant le symbole `$` ou `[["nom_de_la_colonne"]]`. Recalculons ainsi la moyenne des âges :
```{r}
mean(df$age)
mean(df[["age"]])
```
#### Listes {#sec-01365}
La dernière structure de données à connaître est la liste. Elle ressemble à un vecteur, au sens où elle permet de stocker un ensemble d'objets les uns à la suite des autres. Cependant, une liste peut contenir n'importe quel type d'objets. Vous pouvez ainsi construire des listes de matrices, des listes d'*arrays*, des listes mixant des vecteurs, des graphiques, des *DataFrames*, des listes de listes...
Créons ensemble une liste qui va contenir des vecteurs et des matrices à l'aide de la fonction `list.`
```{r}
ma_liste <- list(c(1,2,3,4),
matrix(1, ncol = 3, nrow = 5),
matrix(5, ncol = 3, nrow = 7),
'A'
)
```
Il est possible d'accéder aux éléments de la liste par leur position dans cette dernière en utilisant les doubles crochets `[[ ]]` :
```{r}
print(ma_liste[[1]])
print(ma_liste[[4]])
```
Il est aussi possible de donner des noms aux éléments de la liste et d'utiliser le symbole `$` pour y accéder. Créons une nouvelle liste de vecteurs et donnons-leur des noms avec la fonction `names`.
```{r}
liste2 <- list(c(35, 45, 72, 56, 62),
c(175.5, 180.3, 168.2, 172.8, 167.6),
c(TRUE, TRUE, FALSE, TRUE, TRUE)
)
names(liste2) <- c("age", "taille", "proprietaire")
print(liste2$age)
```
Si vous avez bien suivi, vous devriez avoir compris qu'un *DataFrame* n'est en fait rien d'autre qu'une liste de vecteurs avec des noms!
Bravo! Vous venez de faire le tour des bases du langage R. Vous allez apprendre désormais à manipuler des données dans des *DataFrames*!
## Manipulation de données {#sec-014}
Dans cette section, vous apprendrez à charger et à manipuler des *DataFrames* en vue d'effectuer des opérations classiques de gestion de données.
### Chargement d'un *DataFrame* depuis un fichier {#sec-0141}
Il est rarement nécessaire de créer vos *DataFrames* manuellement. Le plus souvent, vous disposerez de fichiers contenant vos données et utiliserez des fonctions pour les importer dans R sous forme d'un *DataFrame*. Les formats à importer les plus répandus sont :
* *.csv*, soit un fichier texte dont chaque ligne représente une ligne du tableau de données et dont les colonnes sont séparées par un délimiteur (généralement une virgule ou un point-virgule);
* *.dbf*, ou fichier *dBase*, souvent associés à des fichiers d'information géographique au format *ShapeFile*;
* *.xls* et *.xlsx*, soit des fichiers générés par Excel;
* *.json*, soit un fichier texte utilisant la norme d'écriture propre au langage JavaScript.
Plus rarement, il se peut que vous ayez à charger des fichiers provenant de logiciels propriétaires :
* *.sas7bdat* (SAS);
* *.sav* (SPSS);
* *.dta* (STATA).
Pour lire la plupart de ces fichiers, nous utilisons le *package* `foreign` dédié à l'importation d'une multitude de formats. Nous commençons donc par l'installer (`install.packages("foreign")`). Ensuite, nous chargeons cinq fois le même jeu de données enregistré dans des formats différents (*csv*, *dbf*, *dta*, *sas7bdat* et *xlsx*) et nous mesurons le temps nécessaire pour importer chacun de ces fichiers avec la fonction `Sys.time`.
#### Lecture d'un fichier *csv* {#sec-01411}
Pour le format *csv*, il n'est pas nécessaire d'utiliser un *package* puisque R dispose d'une fonction de base pour lire ce format.
```{r}
#| message: false
#| warning: false
t1 <- Sys.time()
df1 <- read.csv("data/priseenmain/SR_MTL_2016.csv",
header = TRUE, sep = ",", dec = ".",
stringsAsFactors = FALSE)
t2 <- Sys.time()
d1 <- as.numeric(difftime(t2, t1, units = "secs"))
cat("Le DataFrame df1 a ", nrow(df1)," observations",
'et ', ncol(df1)," colonnes\n")
```
Rien de bien compliqué! Notez tout de même que :
* Lorsque vous chargez un fichier *csv*, vous devez connaître le **délimiteur** (ou **séparateur**), soit le caractère utilisé pour délimiter les colonnes. Dans le cas présent, il s'agit d'une virgule (spécifiez avec l'argument `sep = ","`), mais il pourrait tout aussi bien être un point virgule (`sep = ";"`), une tabulation (`sep = " "`), etc.
* Vous devez également spécifier le caractère utilisé comme séparateur de décimales. Le plus souvent, ce sera le point (`dec = "."`), mais certains logiciels avec des paramètres régionaux de langue française (notamment Excel) exportent des fichiers *csv* avec des virgules comme séparateur de décimales (utilisez alors `dec = ","`).
* L'argument `header` indique si la première ligne (l'entête) du fichier comprend ou non les noms des colonnes du jeu de données (avec les valeurs `TRUE` ou `FALSE`). Il arrive que certains fichiers *csv* soient fournis sans entête et que le nom et la description des colonnes soient fournis dans un autre fichier.
* L'argument `stringsAsFactors` permet d'indiquer à R que les colonnes comportant du texte doivent être chargées comme des vecteurs de type texte et non de type facteur.
#### Lecture d'un fichier *dbase* {#sec-01412}
Pour lire un fichier *dbase* (.dbf), nous utilisons la fonction `read.dbf` du *package* `foreign` installé précédemment :
```{r}
#| message: false
#| warning: false
library(foreign)
t1 <- Sys.time()
df2 <- read.dbf("data/priseenmain/SR_MTL_2016.dbf")
t2 <- Sys.time()
d2 <- as.numeric(difftime(t2, t1, units = "secs"))
cat("Le DataFrame df2 a ", nrow(df2)," observations",
"et ", ncol(df2)," colonnes\n")
```
Comme vous pouvez le constater, nous obtenons les mêmes résultats qu'avec le fichier *csv*.
#### Lecture d'un fichier *dta* (Stata) {#sec-01413}
Si vous travaillez avec des collègues utilisant le logiciel Stata, il se peut que ces derniers vous partagent des fichiers *dta*. Toujours en utilisant le *package* `foreign`, vous serez en mesure de les charger directement dans R.
```{r}
#| message: false
#| warning: false
t1 <- Sys.time()
df3 <- read.dta("data/priseenmain/SR_MTL_2016.dta")
t2 <- Sys.time()
d3 <- as.numeric(difftime(t2, t1, units = "secs"))
cat("Le DataFrame df3 a ", nrow(df3)," observations ",
"et ", ncol(df3), " colonnes\n", sep = "")
```
#### Lecture d'un fichier *sav* (SPSS) {#sec-01414}
Pour importer un fichier *sav* provenant du logiciel statistique SPSS, utilisez la fonction `read.spss` du *package* `foreign`.
```{r}
#| message: false
#| warning: false
t1 <- Sys.time()
df4 <- as.data.frame(read.spss("data/priseenmain/SR_MTL_2016.sav"))
t2 <- Sys.time()
d4 <- as.numeric(difftime(t2, t1, units = "secs"))
cat("Le DataFrame df4 a ", nrow(df4)," observations ",
"et ", ncol(df4), " colonnes\n", sep = "")
```
#### Lecture d'un fichier *sas7bdat* (SAS) {#sec-01415}
Pour importer un fichier *sas7bdat* provenant du logiciel statistique SAS, utilisez la fonction `read.sas7bdat` du *package* `sas7bdat`. Installez préalablement le *package* (`install.packages("sas7bdat")`) et chargez-le (`library(sas7bdat)`).
```{r}
#| message: false
#| warning: false
library(sas7bdat)
t1 <- Sys.time()
df5 <- read.sas7bdat("data/priseenmain/SR_MTL_2016.sas7bdat")
t2 <- Sys.time()
d5 <- as.numeric(difftime(t2, t1, units = "secs"))
cat("Le DataFrame df5 a ", nrow(df5)," observations ",
"et ", ncol(df5)," colonnes\n", sep = "")
```
#### Lecture d'un fichier *xlsx* (Excel) {#sec-01416}
Lire un fichier Excel dans R n'est pas toujours une tâche facile. Généralement, nous recommandons d'exporter le fichier en question au format *csv* dans un premier temps, puis de le lire avec la fonction `read.csv` dans un second temps ([section @sec-01411]).
Il est néanmoins possible de lire directement un fichier *xlsx* avec le *package* `xlsx`. Ce dernier requiert que le logiciel JAVA soit installé sur votre ordinateur (Windows, Mac ou Linux). Si vous utilisez la version 64 bit de R, vous devrez télécharger et installer la version 64 bit de JAVA. Une fois que ce logiciel tiers est installé, il ne vous restera plus qu'à installer (`install.packages("xlsx")`) et charger (`library(xlsx)`) le *package* `xlsx`. Sous windows, il est possible que vous deviez également installer manuellement le *package* `rJava` et indiquer à R où se trouve JAVA sur votre ordinateur. La procédure est détaillée [ici](https://cimentadaj.github.io/blog/2018-05-25-installing-rjava-on-windows-10/installing-rjava-on-windows-10/).
```{r}
#| message: false
#| warning: false
library(xlsx)
t1 <- Sys.time()
df6 <- read.xlsx(file="data/priseenmain/SR_MTL_2016.xlsx",
sheetIndex = 1,
as.data.frame = TRUE)
t2 <- Sys.time()
d6 <- as.numeric(difftime(t2, t1, units = "secs"))
cat("Le DataFrame df6 a ", nrow(df6)," observations ",
"et ", ncol(df6)," colonnes\n", sep = "")
```
Il est possible d'accélérer significativement la vitesse de lecture d'un fichier *xlsx* en utilisant la fonction `read.xlsx2`. Il faut cependant indiquer à cette dernière le type de données de chaque colonne. Dans le cas présent, les cinq premières colonnes contiennent des données de type texte (`character`), alors que les 43 autres sont des données numériques (`numeric`). Nous utilisons la fonction `rep` afin de ne pas avoir à écrire plusieurs fois *character* et *numeric*.
```{r}
#| echo: true
#| message: false
#| warning: false
library(xlsx)
t1 <- Sys.time()
df7 <- read.xlsx2(file="data/priseenmain/SR_MTL_2016.xlsx",
sheetIndex = 1,
as.data.frame = TRUE,
colClasses = c(rep("character",5), rep("numeric",43))
)
t2 <- Sys.time()
d7 <- as.numeric(difftime(t2, t1, units = "secs"))
cat("Le DataFrame df6 a ", nrow(df7)," observations ",
"et ", ncol(df7)," colonnes\n", sep = "")
```
Si nous comparons les temps d'exécution (@tbl-tableduration), nous constatons que la lecture des fichiers *xlsx* peut être extrêmement longue si nous ne spécifions pas le type des colonnes, ce qui peut devenir problématique pour des fichiers volumineux. Notez également que la lecture d'un fichier *csv* devient de plus en plus laborieuse à mesure que sa taille augmente. Si vous devez un jour charger des fichiers *csv* de plusieurs gigaoctets, nous vous recommandons vivement d'utiliser la fonction `fread` du *package* `data.table` qui est beaucoup plus rapide.
```{r}
#| label: tbl-tableduration
#| tbl-cap: Temps nécessaire pour lire les données en fonction du type de fichiers
#| echo: false
#| message: false
#| warning: false
DureeImportation <- data.frame(
"fonction" = c("read.csv" , "read.dbf" , "read.spss" , "read.dta",
'read.sas7bdat',"read.xlsx" , "read.xlsx2"),
"duree" = c(d1, d2, d3, d4, d5, d6, d7)
)
knitr::kable(DureeImportation,
format.args = list(decimal.mark = ',', big.mark = " "),
digits = 2,
col.names = c("Fonction", "Durée (secondes)"),
align= c("r", "l")
)
```
### Manipulation d'un *DataFrame* {#sec-0142}
Une fois le *DataFrame* chargé, voyons comment il est possible de le manipuler.
#### Petit mot sur le `tidyverse` {#sec-01421}
`tidyverse` est un ensemble de *packages* conçus pour faciliter la structuration et la manipulation des données dans R. Avant d'aller plus loin, il est important d'aborder brièvement un débat actuel dans la Communauté R. Entre 2010 et 2020, l'utilisation du `tidyverse` s'est peu à peu répandue. Développé et maintenu par Hadley Wickham, `tidyverse` introduit une philosophie et une grammaire spécifiques qui diffèrent du langage R traditionnel. Une partie de la communauté a pour ainsi dire complètement embrassé le `tidyverse` et de nombreux *packages*, en dehors du `tidyverse`, ont adopté sa grammaire et sa philosophie. À l'inverse, une autre partie de la communauté est contre cette évolution ([voir l'article du blogue suivant](https://blog.ephorie.de/why-i-dont-use-the-tidyverse){target="_blank"}). Les arguments pour et contre `tidyverse` sont résumés dans le (@tbl-Tidyverse).
```{r}
#| label: tbl-Tidyverse
#| tbl-cap: Avantages et inconvénients du tidyverse
#| echo: false
#| message: false
#| warning: false
df <- data.frame(
Pour = c("Simplicité d'écriture et d'apprentissage",