-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.qmd
856 lines (526 loc) · 33 KB
/
index.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
---
title: "Research Compendium"
subtitle: "Master 2 BEST-ALI 2024-2025"
title-block-banner: images/workflow.png
format:
html:
theme: spacelab
code-fold: false
page-layout: full
editor: source
embed-resources: true
toc: true
toc-title: Au menu aujourd'hui
toc-depth: 4
bibliography: references/references.bib
---
![](images/workflow.png)
::: {.callout-note}
## Objectif
L'objectif de cette session de travaux pratiques est de créer un _**research compendium**_, c.-à-d. un
dossier de travail dont la structure est dérivée de celle d'un package {{< fa brands r-project >}}.
Vous allez découvrir les fichiers importants que nous vous recommandons d'ajouter à
un projet de recherche. Vous allez aussi apprendre à écrire et documenter des fonctions {{< fa brands r-project >}}.
Ce _**research compendium**_ pourra, par exemple, servir de base pour votre travail de stage de Master 2.
:::
**NB.** Ce tutoriel est une version simplifiée de l'exercice proposé par la formation ["Recherche reproductible en écologie numérique"](https://rdatatoolbox.github.io/) du CESAB.
## Préambule
Afin de nous assister dans le développement de notre compendium,
nous allons utiliser les packages {{< fa brands r-project >}}
`usethis` et `devtools`. Ils permettent de faciliter la création de certains fichiers/répertoires
spécifiques à un compendium/package {{< fa brands r-project >}} et d'utiliser à notre avantage les outils de développement de packages {{< fa brands r-project >}}.
::: {layout-ncol=2}
![](images/usethis.png){width="30%"}
![](images/devtools.svg){width="30%"}
:::
{{< fa hand-point-right >}} Installez les packages {{< fa brands r-project >}} `usethis` et `devtools` depuis le CRAN :
```{r}
#| echo: true
#| eval: false
## Installation de `usethis` et `devtools` ----
install.packages("usethis")
install.packages("devtools")
## Chargement des packages -----
library("usethis")
library("devtools")
```
::: {.callout-note}
Comme ces packages ne sont PAS nécessaires à l'execution de nos analyses (ils sont necessaires pour facilement créer un compendium et l'utiliser), nous les installons directement via la console {{< fa brands r-project >}} et les chargeons entièrement via des appels à la fonction `library()`.
:::
## Projet RStudio
{{< fa hand-point-right >}} Créez un nouveau projet RStudio : **_File > New Project > New Directory > New Project_**
- Choisissez un nom pour votre projet (sans signe de ponctuation)
- Sélectionnez l'emplacement où le nouveau projet sera créé
- Décochez toutes les autres cases
- Cochez la case "open in new session"
- Validez
::: {layout-ncol=3}
![](images/rstudio_new_project_1.png)
![](images/rstudio_new_project_2.png)
![](images/rstudio_new_project_3.png)
:::
::: {.callout-tip}
## Bonne pratique
Toujours travailler dans un **Projet RStudio**. Cela présente l'avantage de simplifier les chemins d'accès aux fichiers, notamment avec le package {{< fa brands r-project >}} [`here`](https://here.r-lib.org/) et sa fonction [`here()`](https://here.r-lib.org/reference/here.html) dans les documents quarto. Les chemins d'accès seront toujours construits par rapport au dossier contenant le fichier **.Rproj** (racine du projet). On parle de _chemin relatif_. N'utilisez **plus jamais** la fonction [`setwd()`](https://www.rdocumentation.org/packages/base/versions/3.6.2/topics/getwd).
:::
![](images/setwd_VS_rproj.png){width="50%" fig-align="center"}
## Fichier DESCRIPTION
Le fichier **DESCRIPTION** décrit les métadonnées du projet (titre, auteur, description, dépendances requises, etc.). C'est un des éléments essentiels d'un package {{< fa brands r-project >}}. Ici, nous allons le _détourner_ pour l'utiliser dans le cadre d'un compendium afin de bénéficier des outils de développement de packages {{< fa brands r-project >}}. Ajoutons ce fichier avec la fonction `use_description()` de `usethis`.
```{r}
#| echo: true
#| eval: false
## Ajout d'un fichier DESCRIPTION ----
usethis::use_description(check_name = FALSE)
```
::: {.callout-note}
Notez l'utilisation de `check_name = FALSE` pour pallier les problèmes liés aux restrictions imposées par le CRAN sur les caractères possibles dans les noms de package.
:::
{{< fa hand-point-right >}} Remplissez les champs utiles du fichier **DESCRIPTION** (Title, Authors@R). Vous pourrez remplir le champ "Description" lorsque vous saurez ce que vous faites.
```
Package: basic_compendium
Title: What the Package Does (One Line, Title Case)
Version: 0.0.0.9000
Authors@R:
person("First", "Last", , "first.last@example.com", role = c("aut", "cre"),
comment = c(ORCID = "YOUR-ORCID-ID"))
Description: What the package does (one paragraph).
License: `use_mit_license()`, `use_gpl3_license()` or friends to pick a
license
Encoding: UTF-8
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.3.1
```
::: {.callout-tip}
## Bonne pratique
Toujours ajouter un fichier **DESCRIPTION** à la racine du projet. Il permet de décrire le projet et ses auteurs. On le vera ensuite, il est indispensable pour lister les dépendances et les installer facilement.
:::
## Choix d'une Licence
Tout matériel partagé doit disposer d'une licence qui décrit ce qu'il est
possible de faire avec. Ainsi, nous vous recommandons d'ajouter **dès le début du projet** une licence. Pour trouver une licence appropriée à votre projet, rendez-vous, par exemple, sur cette page : <https://chooser-beta.creativecommons.org/>.
Ajoutons la licence [CC-by](https://usethis.r-lib.org/reference/licenses.html) à notre projet avec la fonction `usethis::use_ccby_license()`.
```{r}
#| echo: true
#| eval: false
## Ajout d'une licence ----
usethis::use_ccby_license()
```
Notez qu'un nouveau fichier a été créé : **LICENSE.md**. Celui-ci détaille le contenu de la license choisie et sera lu par GitHub. Regardez aussi le contenu du fichier **DESCRIPTION** : la section **_License_** a été mise à jour.
::: {.callout-tip}
## Bonne pratique
Toujours ajouter une **LICENSE** à un projet qui sera rendu public. Visitez le site [**creativecommons.org**](https://chooser-beta.creativecommons.org/) pour choisir la plus appropriée à votre projet.
{{< fa lightbulb >}} Si aucune licence n'est renseignée, votre projet est soumis aux règles de la
[No License](https://choosealicense.com/no-permission/) : aucune permission n'est accordée. En
d'autres termes, personne ne peut rien faire avec votre projet (pas d'utilisation, pas de modification, pas de partage, etc.).
:::
:::{.callout-note}
Vous pouvez utiliser le site [**creativecommons.org**](https://chooser-beta.creativecommons.org/) pour obtenir le code source d'un badge reflétant la licence associée à votre compendium :
<p xmlns:cc="http://creativecommons.org/ns#" >This work is licensed under <a href="https://creativecommons.org/licenses/by/4.0/?ref=chooser-v1" target="_blank" rel="license noopener noreferrer" style="display:inline-block;">CC BY 4.0<img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/cc.svg?ref=chooser-v1" alt=""><img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/by.svg?ref=chooser-v1" alt=""></a></p>
:::
## Ajout des répertoires
La prochaine étape consiste en la création de sous-répertoires, chacun ayant un rôle précis. Pour cela, utilisez la fonction `dir.create()`.
```{r}
#| echo: true
#| eval: false
## Ajout de sous-répertoires ----
reps <- c("data", "analyses", "R", "outputs")
lapply(reps, dir.create)
## Plus optimal que ----
# dir.create("data")
# dir.create("analyses")
# dir.create("R")
# dir.create("outputs")
```
::: {.callout-tip}
## Bonne pratique
Un [_**bon Research compendium**_](https://www.youtube.com/watch?v=QuGcoOJKXT8) sera composé de différents sous-répertoires, chacun destiné à accueillir un certain type de fichiers. Par ex. :
- le dossier **data/** contiendra toutes les données brutes nécessaires au projet
- le dossier **outputs/** contiendra tous les résultats générés par les analyses
- le dossier **R/** ne contiendra que des fonctions {{< fa brands r-project >}} (et leurs documentations)
- le dossier **analyses/** contiendra des scripts {{< fa brands r-project >}} (ou des fichiers `.qmd`) qui appeleront les fonctions {{< fa brands r-project >}}. Cette structure peut bien sûr être adaptée selon les besoins et la complexité du projet.
:::
## Données du compendium
Nous voilà fin prêt à travailler !
![un screenshot du pdf réalisé avec le package `magick`, voir le code source dans R/pdf_convert.R ](outputs/williams_natcom_2024.png){fig-align="center"}
Nous utiliserons les données associées à l'étude de @williams_deep_2024 dont voici le résumé :
> Biogeographic history can lead to variation in biodiversity across regions, but it remains unclear how the degree of biogeographic isolation among communities may lead to differences in biodiversity. Biogeographic analyses generally treat regions as discrete units, but species assemblages differ in how much biogeographic history they share, just as species differ in how much evolutionary history they share. Here, we use a continuous measure of biogeographic distance, phylobetadiversity, to analyze the influence of biogeographic isolation on the taxonomic and functional diversity of global mammal and bird assemblages. On average, biodiversity is better predicted by environment than by isolation, especially for birds. However, mammals in deeply isolated regions are strongly influenced by isolation; mammal assemblages in Australia and Madagascar, for example, are much less diverse than predicted by environment alone and contain unique combinations of functional traits compared to other regions. Neotropical bat assemblages are far more functionally diverse than Paleotropical assemblages, reflecting the different trajectories of bat communities that have developed in isolation over tens of millions of years. Our results elucidate how long-lasting biogeographic barriers can lead to divergent diversity patterns, against the backdrop of environmental determinism that predominantly structures diversity across most of the world.
Les auteurs explorent les patrons globaux de dissimilarité phylogénétique des mammifères et des oiseaux au regard de l'environnement et des barrières biogéographiques. Ici nos analyses seront simples, elles visent à apprendre à construire et utiliser un compendium : nous allons rapidement explorer et cartographier les patrons de richesse spécifique pour les oiseaux et les mammifères à l'échelle globale en nous appuyant sur des données générées par @williams_deep_2024.
{{< fa hand-point-right >}} Explorez rapidement les différentes sections de l'article et notez la présence des sections "Data availability" et "Code availability". Les auteurs expliquent comment obtenir les données de base qui soutiennent leurs analyses et fournissent un lien vers le *compendium* associé à leur article.
::: {.callout-note}
Vous pouvez télécharger l'article (en open access) dans un sous répertoire `references` pour y avoir accès facilement.
```{r}
#| echo: true
#| eval: false
## Ajout de sous-répertoires ----
reps <- c("data", "analyses", "R", "outputs", "references")
lapply(reps, dir.create, showWarnings = FALSE)
```
:::
{{< fa hand-point-right >}} Rendez-vous sur le [dépôt github](https://github.com/pwilliams0/Biogeography_and_global_diversity) associé à l'article, explorez le README et le contenu. Pensez-vous pouvoir reproduire (facilement) les analyses de @williams_deep_2024 à l'aide du compendium ?
{{< fa hand-point-right >}} Localisez les fichiers contenant les informations de richesse spécifique pour les oiseaux et les mammifères, notez leurs urls (attention à ne pas récupérer l'url de la page github qui affiche le fichier de données formaté, mais bien l'url du fichier -> bouton "Raw" en haut à droite).
{{< fa hand-point-right >}} Localisez aussi la couche "shapefile" qui correspond à la grille globale utilisée par les auteurs (attention le format "shp" est pénible, il y a plusieurs fichiers pour une seule couche vectorielle).
## Implémentation des fonctions
::: {.callout-note}
## Objectif
Dans cette partie nous allons écrire 2 fonctions {{< fa brands r-project >}} qui vont permettre de télécharger les fichiers de données hébergés sur le dépôt GitHub mentionné ci-dessus. Les fichiers seront enregistrés dans le dossier **data/**.
:::
### Création d'un fichier dans R/
Nous allons d'abord créer un fichier {{< fa brands r-project >}} dans lequel nous écrirons le code source de nos fonctions.
{{< fa hand-point-right >}} Utilisez la fonction [`usethis::use_r()`](https://usethis.r-lib.org/reference/use_r.html) pour créer un fichier `functions.R` dans le dossier **R/**.
```{r}
#| echo: true
#| eval: false
## Creation d'un fichier functions.R dans R/ --
usethis::use_r("functions")
```
### Écriture des fonctions
Nous allons tout d'abord utiliser la fonction [`utils::download.file()`](https://www.rdocumentation.org/packages/utils/versions/3.6.2/topics/download.file) pour développer un code qui télécharge les données de richesse spécifique pour les oiseaux :
```{r}
#| echo: true
#| eval: false
## File name ----
filename <- "bird_SR_cells.csv"
## GitHub directory URL ----
url <- "https://raw.githubusercontent.com/pwilliams0/Biogeography_and_global_diversity/refs/heads/main/Data/"
## Complete data source url ----
source_url <- paste0(url, filename)
## Destination ----
dest_dir <- "data"
dest_path <- file.path(dest_dir, filename)
## Download file ----
utils::download.file(url = source_url,
destfile = dest_path,
mode = "wb")
```
::: {.callout-note}
- Ici nous déclarons le nom du fichier une seule fois et nous nous en servons pour créer l'url de la source des données `source_url` puis le chemin de destination du téléchargement `dest_path`.
- Notez l'utilisation de `paste0()` pour l'url et de `file.path` pour le chemin.
- Notez les commentaires et les indentations pour faciliter la lecture du code.
:::
Pour "transformer" ce code en fonction nous allons l'encapsuler dans une déclaration de fonction {{< fa brands r-project >}}, ici nous choisissons d'appeler la fonction `dl_bird_sr` (pour "download bird species richness") :
```{r}
#| echo: true
#| eval: false
dl_bird_sr <- function() {
## File name ----
filename <- "bird_SR_cells.csv"
## GitHub directory URL ----
url <- "https://raw.githubusercontent.com/pwilliams0/Biogeography_and_global_diversity/refs/heads/main/Data/"
## Complete file url ----
file_url <- paste0(url, filename)
## Destination ----
dest_dir <- "data"
dest_path <- file.path(dest_dir, filename)
## Download file ----
utils::download.file(url = file_url,
destfile = dest_path,
mode = "wb")
return(dest_path)
}
```
::: {.callout-note}
- Une fonction est un objet {{< fa brands r-project >}} comme les autres : on doit choisir son nom et on utilise le symbole d'attribution `<-` pour la déclarer.
- On utilise `return()` en fin de fonction pour retourner à l'utilisateur le résultat de la fonction. Ici on renvoit simplement le chemin de destination du téléchargement.
- Cette fonction n'a pas de *paramètres* (les parenthèses après `function` sont vides : `<- function()`) : aucune information n'est nécessaire à son fonctionnement, la fonction télécharge les données pour les oiseaux, c'est tout.
:::
Nous allons éxecuter notre fonction. Il faut d'abord la rendre disponible à l'utilisation.
{{< fa hand-point-right >}} pour cela il suffit de sélectioner sa définition et de la charger dans la console `ctrl + entrée`.
{{< fa hand-point-right >}} Observez votre environnement, la fonction apparaît.
pour éxecuter la fonction il suffit de l'appeler dans la console :
```{r}
#| echo: true
#| eval: false
dl_bird_sr()
```
Plutôt que de créer une deuxième fonction pour les mammifères nous allons modifier notre fonction pour avoir le choix entre plusieurs fichiers à télécharger (par exemple la richesse spécifique des oiseaux OU celle des mammifères).
{{< fa bulb >}} Nous pouvons ajouter un *paramètre* à notre fonction. Le paramètre devra être renseigné à l'utilisation et sa valeur sera observée par le code de la fonction pour choisir quel fichier télécharger :
```{r}
#| echo: true
#| eval: false
download_sr <- function(taxon) {
## Inform about the data being downloaded
message("# ---- Downloading data for taxon: ", taxon)
## File name ----
if (taxon == "bird") filename <- "bird_SR_cells.csv"
if (taxon == "mamm") filename <- "mamm_SR_cells.csv"
## GitHub directory URL ----
url <- "https://raw.githubusercontent.com/pwilliams0/Biogeography_and_global_diversity/refs/heads/main/Data/"
## Complete file url ----
file_url <- paste0(url, filename)
## Destination ----
dest_dir <- "data"
dest_path <- file.path(dest_dir, filename)
## Download file ----
utils::download.file(url = file_url,
destfile = dest_path,
mode = "wb")
return(dest_path)
}
```
::: {.callout-note}
- Le nom de la fonction à changé ...
- On utilise `if ()` pour observer la valeur de `taxon` renseignée par l'utilisateur.
- On utilise `==` pour tester l'égalité de 2 valeurs (`!=`, `<`, `<=`, `>`, `>=` pour les autres comapraisons)
- On devra obligatoirement renseigner une valeur pour `taxon` lors de l'utilisation de la fonction. Sinon elle ne saura pas quel fichier télécharger : `download_sr(taxon = "bird")` ou `download_sr(taxon = "mamm")`.
- Si on ne renseigne pas de valeur pour `taxon` ou si on reseigne une valeur différente de `"bird"` ou `"mamm"`, alors la fonction échoue et renvoit un message d'erreur. C'est une bonne chose !
:::
Nous allons utiliser cette fonction plus tard, patience. En attendant nettoyons notre environnement car la bonne pratique est de charger les fonctions via un autre mécanisme que nous verrons plus tard.
```{r}
#| echo: true
#| eval: false
rm(dl_bird_sr)
rm(download_sr)
```
::: {.callout-tip}
## Bonne pratique
**Ecrivez des fonctions** : on parle de _Factorisation de code_. Cela rendra votre code plus clair et plus facilement réutilisable. Placez toujours vos fonctions {{< fa brands r-project >}} dans le dossier **R/**. Si vous utilisez des fonctions de dépendances externes, priviligiez cette écriture : `package::fonction()`.
:::
{{< fa hand-point-right >}} Écrivez une fonction `dl_grid_cells` qui télécharge les fichiers "shapefile" de la grille globale.
```{r}
#| echo: true
#| eval: false
dl_grid_cells <- function() {
## Inform about the data being downloaded
message("# ---- Downloading the global grid")
## File names ----
base_name <- "global_cells"
extensions <- c(".shp", ".shx", ".prj", ".dbf")
filenames <- paste0(base_name, extensions)
## GitHub directory URL ----
url <- "https://raw.githubusercontent.com/pwilliams0/Biogeography_and_global_diversity/refs/heads/main/Data/"
## Complete file url ----
file_urls <- paste0(url, filenames)
## Destination ----
dest_dir <- "data"
dest_paths <- file.path(dest_dir, filenames)
## Download files ----
lapply(1:length(file_urls), function(i) {
message("-> ", base_name, extensions[i])
utils::download.file(url = file_urls[i],
destfile = dest_paths[i],
mode = "wb")
})
return(dest_paths)
}
```
## Documentation
Maintenant, documentez votre/vos fonctions. C'est **essentiel !** Pour cela,
ajoutez un entête [**roxygen2**](https://roxygen2.r-lib.org/articles/roxygen2.html) à vos fonctions. Cette syntaxe permet de documenter efficacement toute fonction {{< fa brands r-project >}}.
Cette entête devra contenir (a minima) un titre, une description de chaque argument et le retour de la fonction.
{{< fa lightbulb >}} Pour ajouter une entête **roxygen2** à une fonction existente utlisez le menu **_Code > Insert Roxygen Skeleton_**.
**Proposition de documentation** (explorez)
```{r}
#| echo: true
#| eval: false
#' Download Species Richness Data from Williams et al. 2024
#'
#' @param taxon (bird, mamm) the taxon for which data are downloaded
#'
#' @return the path to the downloaded file
#' @export
#'
download_sr <- function(taxon) { ... }
```
**Optionnel :** transpilez vos entêtes **roxygen2** en fichiers `.Rd`, seuls fichiers acceptés par {{< fa brands r-project >}} pour documenter des fonctions. Ces fichiers `.Rd` seront stockés dans le dossier **man/**.
```{r}
#| echo: true
#| eval: false
## Génération de la doc ----
devtools::document()
```
L'aide de votre fonction est maintenant accessible via `?nom_fonction`.
::: {.callout-tip}
## Bonne pratique
Pensez aux autres (et au vous du futur) : **documentez toujours** votre code. Un code sans documentation est inutile. Utilisez les entêtes **roxygen2** pour documenter vos fonctions {{< fa brands r-project >}}, de simples commentaires pour documenter du code et des `README` pour tout le reste.
:::
## Ajout des dépendances
Nos fonctions contiennent une dépendance à un package externe : [`utils`](https://www.rdocumentation.org/packages/utils/versions/3.6.2). Nous devons ajouter cette dépendance au fichier **DESCRIPTION**. Pour cela, nous allons utiliser la fonction `usethis::use_package()`.
```{r}
#| echo: true
#| eval: false
## Ajout de dépendances ----
usethis::use_package("utils")
```
Regardez le contenu du fichier **DESCRIPTION**. Par défaut, les packages requis sont listés sous le tag **_Imports_**. Ainsi, pour utiliser une fonction externe, il faudra l'appeler par `package::fonction()`.
Si vous remplacer le tag **_Imports_** par **_Depends_** (`?usethis::use_package()`), l'utilisation de la fonction [`devtools::load_all()`](https://www.rdocumentation.org/packages/devtools/versions/2.4.5/topics/load_all) (voir plus bas) aura le même effet qu'un [`library()`](https://www.rdocumentation.org/packages/base/versions/3.6.2/topics/library) et vous pourrez utiliser une fonction externe par `fonction()`. C'est pratique pour les packages comme `ggplot2` qui demande de nombreux appels à leurs fonctions pour réaliser une tâche.
```{r}
#| echo: true
#| eval: false
## Ajout de dépendances ----
usethis::use_package("ggplot2", type = "Depends")
```
::: {.callout-tip}
## Bonne pratique
Listez toujours les **packages requis dans le fichier DESCRIPTION**. Ainsi, vous centralisez la liste des packages requis en un seul endroit.
En plus de la description du projet, il permet de lister les packages dont le projet dépend (tags **_Imports_**, **_Depends_** et **_Remotes_**). Avec ce fichier, plus besoin d'utiliser les fonctions [`install.packages()`](https://www.rdocumentation.org/packages/utils/versions/3.6.2/topics/install.packages) et [`library()`](https://www.rdocumentation.org/packages/base/versions/3.6.2/topics/library).
Elles seront remplacées respectivement par [`devtools::install_deps()`](https://www.rdocumentation.org/packages/devtools/versions/2.4.5/topics/install_deps) et [`devtools::load_all()`](https://www.rdocumentation.org/packages/devtools/versions/2.4.5/topics/load_all).
J'ai besoin d'un nouveau package pour mes analyses, j'utilise **toujours** la procédure suivante :
- je renseigne le package dans DESCRIPTION
- j'execute `devtools::install_deps()` pour l'installer
- j'execute `devtools::load_all()` si j'utilise le champ "Depends" pour pouvoir utliser les fonctions du package (c'est mal), sinon j'utilise (toujours) `package::fonction`.
:::
## Chargement du projet
Maintenant que notre compendium contient les éléments clés d'un package {{< fa brands r-project >}}, c.-à-d. un fichier **DESCRIPTION** et un répertoire **R/**, nous pouvons utiliser les outils de développement des packages {{< fa brands r-project >}}.
Les fonctions {{< fa brands r-project >}} stockées dans le dossier **R/** doivent être chargées avec la fonction [`devtools::load_all()`](https://www.rdocumentation.org/packages/devtools/versions/2.4.5/topics/load_all).
Cette fonction vient remplacer la fonction [`source()`](https://www.rdocumentation.org/packages/base/versions/3.6.2/topics/source) (et la fonction [`library()`](https://www.rdocumentation.org/packages/base/versions/3.6.2/topics/library) si les packages requis sont listés sous le tag **_Depends_** dans le fichier **DESCRIPTION**).
Après chaque modification d'une fonction {{< fa brands r-project >}}, n'oubliez pas d'exécuter la fonction [`devtools::load_all()`](https://www.rdocumentation.org/packages/devtools/versions/2.4.5/topics/load_all).
Essayez ces deux fonctions.
```{r}
#| echo: true
#| eval: false
## Installation des packages manquants ----
devtools::install_deps()
## Chargement des packages et fonctions R ----
devtools::load_all()
```
::: {.callout-tip}
## Bonne pratique
Avec un dossier **R/**, vous pouvez utiliser la fonction [`devtools::load_all()`](https://www.rdocumentation.org/packages/devtools/versions/2.4.5/topics/load_all) (chargement du projet) au lieu de [`library()`](https://www.rdocumentation.org/packages/base/versions/3.6.2/topics/library) et [`source()`](https://www.rdocumentation.org/packages/base/versions/3.6.2/topics/source).
:::
## Appel aux fonctions
Jusqu'à présent, nous n'avons fait que définir des fonctions {{< fa brands r-project >}}, mais nous ne les avons pas exécutées. Nous allons créer notre premier script {{< fa brands r-project >}} dans le dossier **analyses/**. Celui-ci aura pour objectif d'appeler les fonctions {{< fa brands r-project >}} définies précédemment pour télécharger les données.
Créez un nouveau script {{< fa brands r-project >}} comme suit et éditez-le:
```{r}
#| echo: true
#| eval: false
## Ajout d'un script R ----
utils::file.edit("analyses/01_download-data.R")
```
**Proposition de contenu**
```{r}
#| echo: true
#| eval: false
# Download project raw data
#
# This script will download bird and mammal species richness data and the global grid
# from Williams et al. 2024. The files will be stored in `data/`.
#
# All functions used in the script have been developed for this project
# and can be found in the folder R/.
#
# Jane Doe <jane.doe@mail.me>
## Download SR data ----
### birds
download_sr("bird")
### mammals
download_sr("mamm")
## Download the global grid ----
dl_grid_cells()
```
## Ajout d'un make.R
Afin d'automatiser notre projet, nous allons créer un script {{< fa brands r-project >}} à la racine du projet. Nous l'appelerons, par convention, **make.R**. Celui-ci aura deux objectifs : 1) mettre en place le projet et 2) exécuter le projet. L'idée est de n'exécuter que ce script.
{{< fa hand-point-right >}} Créez un fichier `make.R` à la racine du projet, placez-y une entête informative (le nom du compendium, le nom du fichier, votre email). Placez-y aussi les appels à `devtools::install_deps()` pour installer les dépendences et `devtools::load_all()` pour charger les fonctions que vous avez écrites.
```{r}
#| echo: true
#| eval: false
## Ajout du make ----
utils::file.edit("make.R")
```
Contenu du make.R :
```{r}
#| echo: true
#| eval: false
############################################################
# Basic Compendium
# francois.guilhaumon@ird.fr
# make.R
############################################################
# create directories ----
reps <- c("data", "analyses", "R", "outputs", "references")
lapply(reps, dir.create, showWarnings = FALSE)
# install the project dependencies listed in DESCRIPTION ----
devtools::install_deps()
# load the project functions ----
devtools::load_all()
```
::: {.callout-tip}
## Bonne pratique
Un **fichier make.R** placé à la racine du projet permet de facilement mettre en place le projet (installation et chargement des packages requis et des fonctions {{< fa brands r-project >}}) et d'exécuter les différentes analyses de manière séquentielle (en sourçant les scripts {{< fa brands r-project >}} qui appellent eux-même les fonctions {{< fa brands r-project >}}). C'est la **porte d'entrée des analyses**.
:::
{{< fa hand-point-right >}} Finalement, ajoutez une ligne dans le fichier **make.R** qui permettra d'exécuter le script {{< fa brands r-project >}} `analyses/01_download-data.R`.
Utilisez la fonction [`source()`](https://www.rdocumentation.org/packages/base/versions/3.6.2/topics/source) pour cela.
```{r}
#| echo: true
#| eval: false
############################################################
# Basic Compendium
# francois.guilhaumon@ird.fr
# make.R
############################################################
# create directories ----
reps <- c("data", "analyses", "R", "outputs", "references")
lapply(reps, dir.create, showWarnings = FALSE)
# install the project dependencies listed in DESCRIPTION ----
devtools::install_deps()
# load the project functions ----
devtools::load_all()
# download the project data ----
source("analyses/01_download-data.R")
```
Pour charger le projet et lancer les analyses, il suffit d'exécuter ce fichier **make.R**.
```{mermaid}
flowchart LR
A[make.R] --> B[analyses/01_download-data.R]
```
::: {.callout-tip}
## Bonne pratique
Le dossier **analyses/** contient les scripts {{< fa brands r-project >}} qui appellent les fonctions {{< fa brands r-project >}} stockées dans le dossier **R/**. Il peut être ignoré dans le cas de simples analyses. Le code de l'analyse devra alors se trouver dans le **make.R**. A contrario, dans le cas d'analyses complexes, n'hésitez pas à multiplier les scripts {{< fa brands r-project >}} (plutôt que d'avoir un seul gros script).
:::
## Ajout d'un README
Un jour, sûrement, vous verrez comment envoyer ce projet sur GitHub. Pour l'instant, nous allons légèrement anticiper et ajouter un `README` à notre compendium. Ce sera la **vitrine du projet**. Les rôles d'un `README` sont : 1) de présenter le projet, 2) d'expliquer son contenu, et 3) d'expliquer comment l'installer et l'utiliser.
Pour cela, vous allez ajouter un `README.md` (fichier **Markdown**) à la racine de votre projet.
```{r}
#| echo: true
#| eval: false
## Ajout d'un README ----
utils::file.edit("README.md")
```
```
# Basic Compendium
This commpendium takes as example the data associated with the study of Williams et al. (2024) to exemplify the structure of a basic research compendium:
> Williams, P.J., Zipkin, E.F. & Brodie, J.F. Deep biogeographic barriers explain divergent global vertebrate communities. Nat Commun 15, 2457 (2024). https://doi.org/10.1038/s41467-024-46757-z
## Usage
The analyses can be run by executing the commands in [make.R](make.R).
[ ... ]
```
::: {.callout-important}
N'oubliez pas aussi d'éditer les sections **_Title_** et **_Description_** du fichier **DESCRIPTION**.
:::
::: {.callout-tip}
## Bonne pratique
Ajoutez un **README** à votre projet afin d'aider l'utilisateur à comprendre votre projet.
:::
## Encore des fonctions !
Maintenant que nous avons implémenté l'étape de téléchargement des données brutes. Nous pouvons les préparer en vue de futures analyses (étape de préparation des données). Nous disposons de deux fichiers csv qui nous renseignent sur la richesse spécifique dans chaque cellule de la grille globale, pour laquelle nous avons un shapefile. Pour importer et manipuler des données spatiales sous {{< fa brands r-project >}}, le package [`sf`](https://r-spatial.github.io/sf/) est très pertinent.
Créons une fonction qui
- importe le shapefile de la grille globale (fonction [`sf::st_read`](https://r-spatial.github.io/sf/reference/st_read.html)),
- les données contenues dans les deux fichiers csv,
- augmente la table d'attributs de la grille avec les données de richesse (fonction `dplyr::left_join`)
dans le fichier `R/functions.R`.
```{r}
gather_raw_data <- function() {
## import the global grid ----
grid <- sf::st_read("data/global_cells.shp") #head(grid)
## import richness data ----
mamm_sr <- read.csv("data/mamm_SR_cells.csv", row.names = 1)
names(mamm_sr)[names(mamm_sr) == "SR"] <- "mamm_sr"
bird_sr <- read.csv("data/bird_SR_cells.csv", row.names = 1)
names(bird_sr)[names(bird_sr) == "SR"] <- "bird_sr"
## add richness data to the grid
grid <- dplyr::left_join(grid, mamm_sr, by = "cell_id")
grid <- dplyr::left_join(grid, bird_sr, by = "cell_id")
## il y a une majuscule a Realm !!
names(grid) <- tolower(names(grid))
## show the data ?
# plot(grid["mamm_sr"], border = NA)
# plot(grid["bird_sr"], border = NA)
grid
}
```
Documentez la fonction svp. Et mettez à jour le flux d'analyses, cette fois-ci en écrivant directement l'appel à la fonction `basic_compendium::gather_raw_data()` dans le make.R ... Comme cette étape d'assemblage des données ne contient qu'un seul appel à une fonction, on ne va pas créer un scripts dans `analyses` rien que pour cela ...
```{mermaid}
flowchart LR
A[make.R] --> B[analyses/01_download-data.R]
A --> C[gather_raw_data]
```
## Crédits
L'exercice de la formation ["Recherche reproductible en écologie numérique"](https://rdatatoolbox.github.io/) du CESAB à été créé par [Nicolas Casajus](https://nicolascasajus.fr/). Les illustrations ont été créées par [Allison_horst](https://https://allisonhorst.com/).