├── .Rbuildignore
├── .Rprofile
├── .github
├── .gitignore
└── workflows
│ └── render-rmarkdown.yaml
├── .gitignore
├── DESCRIPTION
├── README.Rmd
├── README.md
├── compile_course.R
├── courses
├── 00-first-last-slides.Rmd
├── C00-package-objectives.en.Rmd
├── C00-package_preambule.en.Rmd
├── C01a-package_fusen_discover.en.Rmd
├── C01b-package_express_fusen.en.Rmd
├── C04-comment_interagir_zoom.en.Rmd
├── C05-comment_utiliser_bakacode.en.Rmd
├── C06-pkg_avance_test.en.Rmd
├── C09-pkg_avance_data.en.Rmd
├── C13-git_fusen.en.Rmd
├── C14-data-analyses-packages.en.Rmd
├── images
│ ├── 00_connection.png
│ ├── 01_home.png
│ ├── 02_chapters.png
│ ├── 03_launch.png
│ ├── 04_separator.png
│ ├── 05_slides.png
│ ├── 05_slides_overview.png
│ ├── 06_rstudio_right.png
│ ├── 07_export.png
│ ├── 08_back_home.png
│ ├── 09_back_courses.png
│ ├── 10_rstudio_full.png
│ ├── 11_go_to_chat.png
│ ├── 12_rocket_chat.png
│ ├── 13_resources.png
│ ├── 14_disconnect.png
│ ├── almost-package-no-data.png
│ ├── baka_courses.png
│ ├── baka_courses_launch.png
│ ├── baka_export.png
│ ├── baka_login.png
│ ├── baka_rstudio.png
│ ├── baka_search.png
│ ├── baka_search_slide.png
│ ├── baka_sessions.png
│ ├── baka_toc.png
│ ├── bakacode_long_3.png
│ ├── cruz_classic_fondnoir.png
│ ├── exemple_test.png
│ ├── flat_minimal_skeleton.png
│ ├── fusen-write-package.png
│ ├── fusen_description_file.png
│ ├── fusen_fold_inflate.png
│ ├── fusen_inflate_functions.png
│ ├── fusen_inflate_vignette.png
│ ├── fusen_mytools_complete.png
│ ├── fusen_new_project.png
│ ├── fusen_rmd_folds_pkg.png
│ ├── fusen_skeleton.png
│ ├── fusen_skeleton_desc.png
│ ├── fusen_skeleton_fun.png
│ ├── fusen_start_hello.png
│ ├── marmot.png
│ ├── new_package_fusen_minimal.png
│ ├── new_package_fusen_teaching.png
│ ├── packages-move-function.png
│ ├── pkg_attachment_badges.png
│ ├── pkg_attachment_cran.png
│ ├── pkg_attachment_doc_function.png
│ ├── pkg_attachment_examples.png
│ ├── pkg_attachment_index.png
│ ├── pkg_attachment_vignette.png
│ ├── present_zoom.en.png
│ ├── squirrels_inflated.png
│ ├── squirrels_pkgdown.png
│ ├── squirrels_rmd_html_snapshot.png
│ ├── vignette.png
│ ├── vignette2.png
│ └── zoom_aide.png
└── quizz.Rmd
├── dev_history.R
├── img
├── 00_connection.png
├── 01_home.png
├── 02_chapters.png
├── 03_launch.png
├── 04_separator.png
├── 05_slides.png
├── 05_slides_overview.png
├── 06_rstudio_right.png
├── 07_export.png
├── 08_back_home.png
├── 09_back_courses.png
├── 10_rstudio_full.png
├── 11_go_to_chat.png
├── 12_rocket_chat.png
├── 13_resources.png
├── 14_disconnect.png
├── cruz_classic_fondnoir.png
└── present_zoom.en.png
├── renv.lock
├── renv
├── .gitignore
├── activate.R
└── settings.dcf
├── submission.Rmd
└── teach-package-dev-rmdfirst.Rproj
/.Rbuildignore:
--------------------------------------------------------------------------------
1 | ^renv$
2 | ^renv\.lock$
3 | ^\.github$
4 | ^.*\.Rproj$
5 | ^\.Rproj\.user$
6 |
--------------------------------------------------------------------------------
/.Rprofile:
--------------------------------------------------------------------------------
1 | source("renv/activate.R")
2 |
--------------------------------------------------------------------------------
/.github/.gitignore:
--------------------------------------------------------------------------------
1 | *.html
2 |
--------------------------------------------------------------------------------
/.github/workflows/render-rmarkdown.yaml:
--------------------------------------------------------------------------------
1 | on:
2 | push:
3 | branches:
4 | - main
5 | - master
6 | - the-ci
7 | pull_request:
8 | branches:
9 | - main
10 | - master
11 |
12 | jobs:
13 | build:
14 | runs-on: ubuntu-20.04
15 | env:
16 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
17 | GITLAB_THINKR_PAT: ${{ secrets.GITLAB_THINKR_PAT }}
18 | REPO_NAME: "https://packagemanager.rstudio.com/all/__linux__/focal/latest"
19 | FILL_HOME: "FALSE"
20 | steps:
21 | - name: Checkout repo
22 | uses: actions/checkout@v2
23 | with:
24 | fetch-depth: 0
25 |
26 | - name: Setup R
27 | uses: r-lib/actions/setup-r@v1
28 |
29 | - uses: r-lib/actions/setup-pandoc@v1
30 |
31 | - name: Query dependencies
32 | run: |
33 | install.packages('remotes')
34 | saveRDS(remotes::dev_package_deps(dependencies = TRUE), ".github/depends.Rds", version = 2)
35 | writeLines(sprintf("R-%i.%i", getRversion()$major, getRversion()$minor), ".github/R-version")
36 | shell: Rscript {0}
37 |
38 | - name: Install system dependencies
39 | if: runner.os == 'Linux'
40 | run: |
41 | while read -r cmd
42 | do
43 | eval sudo $cmd
44 | done < <(Rscript -e 'writeLines(remotes::system_requirements("ubuntu", "20.04"))')
45 |
46 | - name: Cache Renv packages
47 | uses: actions/cache@v2
48 | with:
49 | path: $HOME/.local/share/renv
50 | key: r-${{ hashFiles('renv.lock') }}
51 | restore-keys: r-
52 |
53 | - name: Install packages
54 | run: |
55 | source("renv/activate.R")
56 | install.packages("git2r")
57 | install.packages("remotes")
58 | options(renv.auth.formation = list(GIT_PAT = Sys.getenv("GITLAB_THINKR_PAT")))
59 | renv::restore()
60 | tmpform <- tempfile(pattern = "form-")
61 | git2r::clone("https://forge.thinkr.fr/thinkr/thinkrverse/formation", local_path = tmpform,
62 | credentials = git2r::cred_user_pass("gitlab-ci-token", Sys.getenv("GITLAB_THINKR_PAT")))
63 | remotes::install_local(path = tmpform, upgrade = FALSE, force = TRUE)
64 | # Rscript -e 'options(remotes.git_credentials = git2r::cred_user_pass("gitlab-ci-token", Sys.getenv("GITLAB_THINKR_PAT")));renv::restore()'
65 | shell: Rscript {0}
66 |
67 | # Mettre les options pour avec renv, qui n'est pas pareil que remotes...
68 |
69 | - name: Render Rmarkdown files
70 | run: |
71 | source("compile_course.R")
72 | dir.create("public")
73 | file.copy("les_cours/complet/support", "public", recursive = TRUE)
74 | writeLines("!*.html\n!*.pdf\n!*_files/", "public/support/.gitignore")
75 | shell: Rscript {0}
76 |
77 | - name: Deploy
78 | uses: peaceiris/actions-gh-pages@v3
79 | with:
80 | github_token: ${{ secrets.GITHUB_TOKEN }}
81 | publish_dir: ./public/support
82 | force_orphan: true
83 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .Rproj.user
2 | .Rhistory
3 | .RData
4 | .Ruserdata
5 | *.html
6 | *.md
7 | *_files/
8 | !README.md
9 | token.txt
10 | les_cours
11 | admin/
12 |
--------------------------------------------------------------------------------
/DESCRIPTION:
--------------------------------------------------------------------------------
1 | Package: user2021.rmdd
2 | Title: What the Package Does (One Line, Title Case)
3 | Version: 0.0.0.9000
4 | Authors@R:
5 | person("First", "Last", , "first.last@example.com", role = c("aut", "cre"),
6 | comment = c(ORCID = "YOUR-ORCID-ID"))
7 | Description: What the package does (one paragraph).
8 | License: `use_mit_license()`, `use_gpl3_license()` or friends to pick a
9 | license
10 | Imports:
11 | attachment,
12 | dplyr,
13 | flextable,
14 | fusen,
15 | git2r,
16 | here,
17 | knitr,
18 | remotes,
19 | testthat,
20 | usethis,
21 | xaringan,
22 | xaringanExtra
23 | Suggests:
24 | future,
25 | purrr,
26 | tidyverse
27 | Remotes:
28 | gadenbuie/xaringanExtra
29 | Encoding: UTF-8
30 | LazyData: true
31 | Roxygen: list(markdown = TRUE)
32 | RoxygenNote: 7.1.1
33 |
--------------------------------------------------------------------------------
/README.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | output: github_document
3 | ---
4 |
5 |
6 |
7 | ```{r, include = FALSE}
8 | knitr::opts_chunk$set(
9 | collapse = TRUE,
10 | comment = "#>"
11 | )
12 | ```
13 |
14 | # How to build a package with "Rmd First" method
15 |
16 | > Build reproducible and shareable data analyses using R packages
17 |
18 |
19 |
20 |
21 |
22 | This repository contains the course material of our [useR! 2021 tutorial](https://user2021.r-project.org/), then [AFH 2022](https://www.association-francaise-halieutique.fr).
23 |
24 | Instructors: [Sébastien Rochette](https://statnmap.com), Florence Mounier
25 |
26 | ## Tutorial purpose
27 |
28 | The tutorial is designed for R users from a variety of fields who are interested in organizing their analyses or development, usually written in RMarkdown files, into R packages.
29 |
30 | ## Modifications
31 |
32 | Please use a branch to add modifications and open a merge request to ask to add them in the _master_. You can assign me to this.
33 |
34 | ## Content of this repository
35 |
36 | - `courses/`: Rmd for different courses
37 | - `data/`: shapefiles and data used in the slides and in exercises
38 | - `exercises/` : Rmd of the exercises with complete answers
39 | - `submission.Rmd` : Tutorial submission
40 |
41 | ## What we proposed
42 |
43 | ### Abstract
44 |
45 | "Rmd First" method can reduce mental load when building packages by keeping users in a natural environment, using a tool they know: a RMarkdown document.
46 |
47 | The step between writing your own R code to analyze some data and refactoring it into a well-documented, ready-to-share R package seems unreachable to many R users.
48 | The package structure is sometimes perceived as useful only for building general-purpose tools for data analysis to be shared on official platforms.
49 | However, packages can be used for a broader range of purposes, from internal use to open-source sharing.
50 | Because packages are designed for robustness and enforce helpful standards for documentation and testing, the package structure provides a useful framework for refactoring analyses and preparing them to go into production.
51 | The following approach to write a development or an analysis inside a Rmd, will significantly reduce the work to transform a Rmd into a package :
52 |
53 | - _Design_ : define the goal of your next steps and the tools needed to reach them
54 | - _Prototype_ : use some small examples to prototype your script in Rmd
55 | - _Build_ : Build your script as functions and document your work to be able to use them, in the future, on real-life datasets
56 | - _Strengthen_ : Create tests to assure stability of your code and follow modifications through time
57 | - _Deploy_ : Transform as a well-structured package to deploy and share with your community
58 |
59 | During this tutorial, we will work through the steps of Rmd Driven Development to persuade attendees that their experience writing R code means that they already know how to build a package. They only need to be in a safe environment to find it out, which will be what we propose.
60 | We will take advantage of all existing tools such as {devtools}, {testthat}, {attachment} and {usethis} that ease package development from Rmd to building a package.
61 | The recent package [{fusen}](https://thinkr-open.github.io/fusen), which "inflates a package from a simple flat Rmd", will be presented to further reduce the step between well-designed Rmd and package deployment.
62 | Attendees will leave this workshop having built their first package with the "Rmd First" method and with the skills and tools to build more packages on their own.
63 |
64 | ### The learning goals
65 |
66 | By the end of the tutorial participants should:
67 |
68 | - understand the methodology proposed by Rmd Driven Development
69 | - be able to refactor their code into correctly formatted functions
70 | - understand the structure of a package
71 | - be able to build a documented and tested R package
72 | - know how to share their work with the community on GitHub
73 |
74 | ## What can you do after this tutorial?
75 |
76 | - Practice again, following complementary 'Rmd-first' / 'RMDD' presentations
77 | + https://rtask.thinkr.fr/when-development-starts-with-documentation/
78 | + https://emilyriederer.netlify.com/post/rmarkdown-driven-development/
79 | + https://malco.io/talk/you-re-already-ready-zen-and-the-art-of-r-package-development-rsg/
80 |
81 | - Try ["{fusen}: inflate a package from a simple flat Rmd"](https://rtask.thinkr.fr/fusen-create-a-package-from-a-single-rmarkdown-file/)
82 |
83 | # For instructors
84 |
85 | The content will be built using an internal ThinkR package called {formation}.
86 | This ensures that the HTML output, datasets, and extra files are stored in the correct place to be added to the ThinkR e-learning platform.
87 | Each instructor is still able to locally knit each chapter using {xaringan}.
88 | The content of the course is:
89 |
90 | - courses/C00-package-objectives.en.Rmd: What we will present during this tutorial, and how it will be held
91 | - courses/00-cruz.Rmd: How the e-learning platform works
92 | - courses/C00-package_preambule.en.Rmd: What means package first ?
93 | - courses/C01a-package_fusen_discover.en.Rmd: Discover the structure of a package with {fusen}
94 | - courses/C01b-package_express_fusen.en.Rmd: Build a package using {fusen}
95 |
96 | - courses/C09-pkg_avance_data.en.Rmd: Include datasets in your package
97 | - courses/C13-git_fusen.en.Rmd: Use git with {fusen} projects
98 | - courses/C14-data-analyses-packages.en.Rmd: What about data analyses in a package?
99 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | # How to build a package with “Rmd First” method
5 |
6 | > Build reproducible and shareable data analyses using R packages
7 |
8 |
9 |
10 |
11 | This repository contains the course material of our [useR! 2021
12 | tutorial](https://user2021.r-project.org/), then [AFH
13 | 2022](https://www.association-francaise-halieutique.fr).
14 |
15 | Instructors: [Sébastien Rochette](https://statnmap.com), Florence
16 | Mounier
17 |
18 | ## Tutorial purpose
19 |
20 | The tutorial is designed for R users from a variety of fields who are
21 | interested in organizing their analyses or development, usually written
22 | in RMarkdown files, into R packages.
23 |
24 | ## Modifications
25 |
26 | Please use a branch to add modifications and open a merge request to ask
27 | to add them in the *master*. You can assign me to this.
28 |
29 | ## Content of this repository
30 |
31 | - `courses/`: Rmd for different courses
32 | - `data/`: shapefiles and data used in the slides and in exercises
33 | - `exercises/` : Rmd of the exercises with complete answers
34 | - `submission.Rmd` : Tutorial submission
35 |
36 | ## What we proposed
37 |
38 | ### Abstract
39 |
40 | “Rmd First” method can reduce mental load when building packages by
41 | keeping users in a natural environment, using a tool they know: a
42 | RMarkdown document.
43 |
44 | The step between writing your own R code to analyze some data and
45 | refactoring it into a well-documented, ready-to-share R package seems
46 | unreachable to many R users. The package structure is sometimes
47 | perceived as useful only for building general-purpose tools for data
48 | analysis to be shared on official platforms. However, packages can be
49 | used for a broader range of purposes, from internal use to open-source
50 | sharing. Because packages are designed for robustness and enforce
51 | helpful standards for documentation and testing, the package structure
52 | provides a useful framework for refactoring analyses and preparing them
53 | to go into production. The following approach to write a development or
54 | an analysis inside a Rmd, will significantly reduce the work to
55 | transform a Rmd into a package :
56 |
57 | - *Design* : define the goal of your next steps and the tools needed
58 | to reach them
59 | - *Prototype* : use some small examples to prototype your script in
60 | Rmd
61 | - *Build* : Build your script as functions and document your work to
62 | be able to use them, in the future, on real-life datasets
63 | - *Strengthen* : Create tests to assure stability of your code and
64 | follow modifications through time
65 | - *Deploy* : Transform as a well-structured package to deploy and
66 | share with your community
67 |
68 | During this tutorial, we will work through the steps of Rmd Driven
69 | Development to persuade attendees that their experience writing R code
70 | means that they already know how to build a package. They only need to
71 | be in a safe environment to find it out, which will be what we propose.
72 | We will take advantage of all existing tools such as {devtools},
73 | {testthat}, {attachment} and {usethis} that ease package development
74 | from Rmd to building a package. The recent package
75 | [{fusen}](https://thinkr-open.github.io/fusen), which “inflates a
76 | package from a simple flat Rmd”, will be presented to further reduce the
77 | step between well-designed Rmd and package deployment. Attendees will
78 | leave this workshop having built their first package with the “Rmd
79 | First” method and with the skills and tools to build more packages on
80 | their own.
81 |
82 | ### The learning goals
83 |
84 | By the end of the tutorial participants should:
85 |
86 | - understand the methodology proposed by Rmd Driven Development
87 | - be able to refactor their code into correctly formatted functions
88 | - understand the structure of a package
89 | - be able to build a documented and tested R package
90 | - know how to share their work with the community on GitHub
91 |
92 | ## What can you do after this tutorial?
93 |
94 | - Practice again, following complementary ‘Rmd-first’ / ‘RMDD’
95 | presentations
96 | -
97 | -
98 | -
99 | - Try [“{fusen}: inflate a package from a simple flat
100 | Rmd”](https://rtask.thinkr.fr/fusen-create-a-package-from-a-single-rmarkdown-file/)
101 |
102 | # For instructors
103 |
104 | The content will be built using an internal ThinkR package called
105 | {formation}. This ensures that the HTML output, datasets, and extra
106 | files are stored in the correct place to be added to the ThinkR
107 | e-learning platform.
108 | Each instructor is still able to locally knit each chapter using
109 | {xaringan}.
110 | The content of the course is:
111 |
112 | - courses/C00-package-objectives.en.Rmd: What we will present during
113 | this tutorial, and how it will be held
114 | - courses/00-cruz.Rmd: How the e-learning platform works
115 | - courses/C00-package_preambule.en.Rmd: What means package first ?
116 | - courses/C01a-package_fusen_discover.en.Rmd: Discover the structure
117 | of a package with {fusen}
118 | - courses/C01b-package_express_fusen.en.Rmd: Build a package using
119 | {fusen}
120 |
121 | - courses/C09-pkg_avance_data.en.Rmd: Include datasets in your package
122 | - courses/C13-git_fusen.en.Rmd: Use git with {fusen} projects
123 | - courses/C14-data-analyses-packages.en.Rmd: What about data analyses
124 | in a package?
125 |
--------------------------------------------------------------------------------
/compile_course.R:
--------------------------------------------------------------------------------
1 | # Compile Courses for SC platform
2 | library(tidyverse)
3 | library(formation)
4 |
5 | # Compiler en parallèle
6 | future::plan(future::multisession(workers = 4)) # Parallèle
7 | # plan(sequential) # Non parallèle. Default.
8 |
9 | # Client - Nom de dossier
10 | client_dir <- "afh2022"
11 |
12 | # Combien de sessions
13 | all_sessions <- c("1") # Nom des sessions
14 | all_dates <- paste(28, "June 2022") # Dates des sessions
15 |
16 | # First and last slides
17 | # first_last_slides
18 | # formation::support() %>% cat(file = "first_last.Rmd")
19 |
20 | # Create logo useR bottom
21 | # cat('.remark-slide-number-left {
22 | # background: url("', knitr::image_uri("img/userlogo-small.png"),'") no-repeat left top;
23 | # background-size: 20px;
24 | # }
25 | # .prez_github {
26 | # background: #ffffffd4;
27 | # }
28 | # ', sep = "",
29 | # file = "prez.css")
30 |
31 |
32 | # Partial - Create course - Nom du (de la) formateur.trice ====
33 | create_session <- purrr::partial(
34 | formation::create_session,
35 | title = "Build reproducible and shareable data analyses using R packages",
36 | formateur = "Sébastien Rochette, Florence Mounier",
37 | email = "sebastien@thinkr.fr, florence@thinkr.fr",
38 | telephone = "",
39 | dossier = here::here(),
40 | render_pdf = c("none", "pagedown")[2],
41 | types = c("stagiaire", "formateur")[1],
42 | # dataWD = dataWD,
43 | footer = "S. Rochette, F. Mounier",
44 | # add_footer_chapitre = FALSE,
45 | url = "AFH 2022 - tutorial",
46 | # css = here::here("prez.css"),
47 | # logo_home = here::here("courses/images/marmot.png"),
48 | first_last_slides = here::here("courses/00-first-last-slides.Rmd"),
49 | first_last_slides_seal = FALSE,
50 | ... =
51 | )
52 |
53 | # Listes des supports de cours ====
54 | tous_les_cours <- list(
55 | cours_1 = c(
56 | "courses/C00-package-objectives.en.Rmd",
57 | # "courses/00-cruz.Rmd"#,
58 | "courses/C05-comment_utiliser_bakacode.en.Rmd",
59 | # "courses/C04-comment_interagir_zoom.en.Rmd",
60 | "courses/C00-package_preambule.en.Rmd",
61 | "courses/C01a-package_fusen_discover.en.Rmd",
62 | "courses/C01b-package_express_fusen.en.Rmd",
63 | # "courses/C06-pkg_avance_test.en.Rmd"#,
64 | "courses/C09-pkg_avance_data.en.Rmd",
65 | "courses/C13-git_fusen.en.Rmd",
66 | "courses/C14-data-analyses-packages.en.Rmd"
67 | )
68 | )
69 |
70 | # Projets avec data, exos et td ----
71 | # il faut définir des projet et leur contenus
72 | # les element qui s'appellent
73 | # - "empty" vont etre preparé comme exos, en vidant les chunk d'exo,
74 | # - "render" comme "empty", mais en plus l'exercice est compilé en HTML dans le dossier
75 | # - "formateur" : les fichiers à déplacer dans le dossier formateur uniquement
76 | # - les autres (avec ou sans nom) sont déposés tel quel dans le dossier
77 |
78 | # Do not create home on Github Actions
79 | if (Sys.getenv("FILL_HOME", unset = "TRUE") == "TRUE") {
80 | # Create empty fusen packages
81 | dirfusen <- tempfile(pattern = "fusen-")
82 | dir.create(dirfusen)
83 | mytools <- file.path(dirfusen, "mytools.solution")
84 | hello <- file.path(dirfusen, "hello.solution")
85 | wd <- getwd()
86 |
87 | usethis::with_project(path = dirfusen, {
88 | # mytools
89 | dir.create(mytools, recursive = TRUE)
90 | fusen::add_flat_template(pkg = mytools, flat_name = "teaching", open = FALSE)
91 | # hello
92 | dir.create(hello, recursive = TRUE)
93 | fusen::add_flat_template(pkg = hello, flat_name = "minimal", open = FALSE)
94 | }, force = TRUE)
95 |
96 | setwd(wd)
97 |
98 | home <- list(
99 | projet1 = list(
100 | root = c(
101 | formateur = "courses/quizz.Rmd"# ,
102 | # render = "nyc_squirrels_rmd/nyc_squirrels_rmd_simple.Rmd"
103 | ),
104 | data = c(
105 | # "nyc_squirrels_rmd"
106 | )
107 | ),
108 | mytools.solution = list(
109 | root = c(file.path(mytools, "dev"))
110 | ),
111 | hello.solution = list(
112 | root = c(file.path(hello, "dev"))
113 | )
114 | )
115 | }
116 |
117 | # All sessions - Normally used
118 | if (TRUE) {
119 | create_session(
120 | tous_les_cours, client_dir,
121 | which_cours = 1:seq_along(all_sessions),
122 | which_session = all_sessions,
123 | which_date = paste(all_dates[c(1, length(all_dates))], collapse = " - "),
124 | output_pattern = "complet",
125 | output_dir = "complet"
126 | )
127 | }
128 |
129 | # Do not create home on Github Actions
130 | if (Sys.getenv("FILL_HOME", unset = "TRUE") == "TRUE") {
131 | # Fonction - peuple_home() ----
132 | formation::peuple_home(home = home, dossier = paste0(client_dir, "_home"))
133 | formation::copy_pdf()
134 | # Fonction - export_pour_sc() ----
135 | # formation::export_pour_sc(pattern = client_dir)
136 | }
137 |
--------------------------------------------------------------------------------
/courses/00-first-last-slides.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Build reproducible and shareable data analyses using R packages"
3 | subtitle: "AFH 2022"
4 | output:
5 | formation::chapitre:
6 | seal: false
7 | add_auto_title_slide: true
8 | add_footer_chapitre: false
9 | xaringan::moon_reader: default
10 | ---
11 | class: center middle inverse title-slide
12 |
13 | ```{r include=FALSE}
14 | knitr::opts_chunk$set(
15 | cache = FALSE,
16 | message = FALSE,
17 | warning = FALSE,
18 | eval = TRUE
19 | )
20 | ```
21 |
22 | ```{r xaringanExtra-search, echo=FALSE}
23 | xaringanExtra::use_search(show_icon = TRUE, case_sensitive = FALSE, position = "top-right")
24 | # xaringanExtra::use_xaringan_extra("tile_view")
25 | # xaringanExtra::style_search(match_background = "pink")
26 | ```
27 |
28 |
38 |
39 | .top_left[
40 | ```{r logo, echo=FALSE, out.width="20%", eval=TRUE}
41 | # knitr::include_graphics("images/marmot.png")
42 | ```
43 | ]
44 |
45 |
46 | # "Build reproducible and shareable data analyses using R packages
47 |
48 | ## _Conférence AFH 2022_
49 |
50 | ### Sébastien Rochette, Florence Mounier
51 |
52 | .prez_github[
53 | Material of this course is on Github: statnmap/teach-package-dev-rmdfirst
54 | ]
55 |
56 | ---
57 |
58 | layout:true
59 | .remark-slide-number-left[`r '\u200B'`]
60 |
61 | ---
62 | class: slide
63 |
64 | ## Thanks for joining this tutorial!
65 |
66 | ### Sébastien Rochette, Florence Mounier
67 | ### sebastien@thinkr.fr, florence@thinkr.fr
68 |
69 | Material of this course is on Github (with answers): statnmap/teach-package-dev-rmdfirst
70 |
71 | ```{r meetup-lille-21, out.width="50%", echo=FALSE}
72 | knitr::include_graphics("images/fusen-write-package.png")
73 | ```
74 |
--------------------------------------------------------------------------------
/courses/C00-package-objectives.en.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "One step package building"
3 | subtitle: "From Rmd to package"
4 | code: "M13S01C00"
5 | prerequis: [""]
6 | output: formation::chapitre
7 | obj_pred: ["Objectives of the course"]
8 | slug: package-flash-build
9 | ---
10 | class: slide
11 |
12 | ```{r, results='asis', eval=FALSE, echo=FALSE}
13 | # cat('')
18 | ```
19 |
20 |
21 | ### Learning goals
22 |
23 | - Understand the methodology proposed by the "Rmd First" method
24 | - Be able to refactor a code into correctly formatted functions
25 | - Understand the structure of a package
26 | - Be able to build a documented and tested R package
27 |
28 | ---
29 | class: slide
30 |
31 | ### Building a package in a few steps
32 |
33 | - Start with a Rmd
34 | - Build your functions inside
35 | - Document your functions
36 | - Inflate as a Package
37 |
38 | .pull-left[
39 | ```{r, echo=FALSE, out.width="90%"}
40 | knitr::include_graphics("images/squirrels_rmd_html_snapshot.png")
41 | ```
42 |
43 | ]
44 | .pull-right[
45 | ```{r, echo=FALSE, out.width="90%"}
46 | knitr::include_graphics("images/squirrels_inflated.png")
47 | ```
48 | ]
49 |
50 | ---
51 | class: slide
52 |
53 | ### How this tutorial will be held
54 |
55 | - E-learning platform: https://bakacode.io
56 | - Instructors speak on slides
57 |
58 |
59 | - Quizz where every attendees will be able to participate
60 | - Direct questions where attendees are asked to participate
61 | - Hands-on parts, in breakout rooms, where attendees are asked to share their screens for instructors to help
62 | - A 5 minutes break every hour
63 | - We stop 15 minutes before the end to say goodbye
64 |
65 |
66 | ---
67 | class: slide
68 |
69 | ### Code of Conduct
70 |
71 | All conference participants agree to:
72 |
73 | - Be considerate in language and actions, and respect the boundaries of fellow participants.
74 | - Refrain from demeaning, discriminatory, or harassing behaviour and language.
75 | - Alert a member of the ThinkR team if you notice someone in distress, or observe violations of this code of conduct, even if they seem inconsequential.
76 |
77 |
78 |
--------------------------------------------------------------------------------
/courses/C00-package_preambule.en.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Start with the documentation"
3 | subtitle: "What are vignettes?"
4 | code: "M13S01C00"
5 | prerequis: [""]
6 | output:
7 | formation::chapitre: default
8 | xaringan::moon_reader: default
9 | obj_pred: ["know what is a vignette"]
10 | slug: package-preambule-en
11 | ---
12 | class: slide
13 |
14 | ```{r echo=FALSE, include=FALSE}
15 | library(dplyr)
16 | ```
17 |
18 |
19 | ### Do you know package {attachment}?
20 |
21 | Let's say you don't!
22 |
23 | #### How to discover what does a package?
24 |
25 | ---
26 | class: slide
27 |
28 | ### How to discover what does a package?
29 | #### My questions as a user
30 |
31 | - What does it do?
32 | - How to install it with its dependencies?
33 | - What are its function?
34 | - How to fill parameters of this function?
35 | - Can I have an example on how to use this function?
36 | - Can I have an example on how to use the package as a whole?
37 | - Will it work with the last version of R and dependencies?
38 |
39 | ---
40 | class: slide
41 |
42 | ### How to discover what does a package?
43 | #### What does it do?
44 |
45 | - CRAN page: https://cran.r-project.org/web/packages/attachment/index.html
46 |
47 | ```{r, echo=FALSE}
48 | knitr::include_graphics("images/pkg_attachment_cran.png")
49 | ```
50 |
51 | ---
52 | class: slide
53 |
54 | ### How to discover what does a package?
55 | #### How to install it with its dependencies?
56 |
57 | - `install.packages('attachment')`
58 |
59 | ???
60 |
61 | You don't have to think about dependencies...
62 | The developers prepared everything for you
63 |
64 | ---
65 | class: slide
66 |
67 | ### How to discover what does a package?
68 | #### What are its functions?
69 |
70 | - Index of the package
71 |
72 | ```{r echo=FALSE, out.width="70%"}
73 | knitr::include_graphics("images/pkg_attachment_index.png")
74 | ```
75 |
76 | ---
77 | class: slide
78 |
79 | ### How to discover what does a package?
80 | #### How to fill parameters of this function?
81 |
82 | - `?att_amend_desc`
83 |
84 | ```{r echo=FALSE, out.width="70%"}
85 | knitr::include_graphics("images/pkg_attachment_doc_function.png")
86 | ```
87 |
88 | ---
89 | class: slide
90 |
91 | ### How to discover what does a package?
92 | #### Can I have an example on how to use this function?
93 |
94 | - `?att_amend_desc` => Examples
95 |
96 | ```{r echo=FALSE, out.width="90%"}
97 | knitr::include_graphics("images/pkg_attachment_examples.png")
98 | ```
99 |
100 | ---
101 | class: slide
102 |
103 | ### How to discover what does a package?
104 | #### Can I have an overview on how to use the package as a whole?
105 |
106 | - Vignettes
107 | - GitHub: https://thinkr-open.github.io/attachment/articles/fill-pkg-description.html
108 |
109 | ```{r echo=FALSE, out.width="50%"}
110 | knitr::include_graphics("images/pkg_attachment_vignette.png")
111 | ```
112 |
113 | ---
114 | class: slide
115 |
116 | ### How to discover what does a package?
117 | #### Will it work with the last version of R and dependencies?
118 |
119 | - README Check, https://github.com/ThinkR-open/attachment
120 | - Unit tests, code coverage, Continuous Integration
121 |
122 | ```{r echo=FALSE, out.width="80%"}
123 | knitr::include_graphics("images/pkg_attachment_badges.png")
124 | ```
125 |
126 | ???
127 |
128 | Unit tests and CI are set up by developers to ensure reproducibility and maintainability
129 |
130 | ---
131 | class: slide
132 |
133 | ### How to discover what does a package?
134 | #### My answers as a user
135 |
136 | ```{r, echo=FALSE}
137 | tribble(
138 | ~Questions, ~Answers,
139 | "What does it do?", "CRAN page",
140 | "How to install it with its dependencies?", "`install.packages('attachment')`",
141 | "What are its functions?", "`?attachment` => Index",
142 | "How to fill parameters of this function?", "`?att_amend_desc`",
143 | "Can I have an example on how to use this function?", "`?att_amend_desc` => Examples",
144 | "Can I have an overview on how to use the package as a whole?", "Vignettes, GitHub",
145 | "Will it work with the last version of R and dependencies?", "README Check"
146 | ) %>%
147 | knitr::kable()
148 | ```
149 |
150 | _There is a dedicated website that gathers all these answers: https://thinkr-open.github.io/attachment/_
151 |
152 | ???
153 |
154 | We will explore this website later
155 |
156 |
157 | ---
158 | class: slide
159 |
160 | ### How to discover what does a package?
161 | #### Developers point of view
162 |
163 | - All these sources of information are adressed by developers
164 |
165 | --
166 |
167 | #### If you start with the documentation, from the vignette, you will not have to think too much about all of these
168 |
169 | ???
170 |
171 | You will build all the doc along the way
172 |
173 | ---
174 | class: slide
175 |
176 | ### Let's talk again about vignettes
177 |
178 | + HTML pages telling the stories of the package
179 | + List vignettes using: `vignette(package = "thepackage")`.
180 |
181 | ```{r, echo=FALSE, out.width="90%"}
182 | knitr::include_graphics("images/vignette.png")
183 | ```
184 |
185 | ---
186 | class: slide
187 |
188 | ### Let's talk again about vignettes
189 |
190 | #### Content of a vignette
191 |
192 | ```{r eval=FALSE}
193 | vignette(topic = "colwise", package = "dplyr")
194 | ```
195 |
196 | ```{r, echo=FALSE, out.width="60%"}
197 | knitr::include_graphics("images/vignette2.png")
198 | ```
199 |
200 | ???
201 |
202 | The story of the package as a whole
203 |
204 | ---
205 | class: slide
206 |
207 | ### Let's talk again about vignettes
208 |
209 | #### Vignette = Rmarkdown (usually)
210 |
211 | - What is the story of the package
212 | - What is the function for
213 | - How to use it with or without parameters
214 | - Reproducible examples
215 | - Different outputs depending on chosen parameters
216 |
217 | --
218 |
219 | #### Let's start building our package from its story !
220 |
221 | ---
222 | class: slide
223 |
224 | ### Quizz: What is a vignette?
225 |
226 | - A: A website somewhere on Internet
227 | - B: A Sticker you can add on your laptop
228 | - C: A R script with the help of function accessible in the installed package
229 | - D: A html page built from a Rmd file, accessible in the installed package
230 |
231 |
232 | ---
233 | class: slide
234 |
235 | ### Quizz: Have you already built a package with all these?
236 |
237 | - A: Yes, everything. Functions, examples, tests, vignettes
238 | - B: Only part of documentation. Functions, examples, maybe vignettes
239 | - C: Only functions in a R/ directory
240 | - D: No. I never built a package from scratch
241 |
--------------------------------------------------------------------------------
/courses/C01a-package_fusen_discover.en.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Discover the structure of a package with {fusen}"
3 | subtitle: "Where does all of this come from?"
4 | code: "M13S01C04"
5 | prerequis: ["M13S01C00"]
6 | output:
7 | formation::chapitre: default
8 | xaringan::moon_reader: default
9 | obj_pred: ["discover the structure of a package"]
10 | slug: package-fusen-discover-en
11 | ---
12 | class: slide
13 |
14 | ```{r include=FALSE}
15 | # Verify {fusen} works here
16 | library(fusen)
17 | library(testthat)
18 |
19 | # Create a new project
20 | dummypackage <- tempfile("inflate.tests")
21 | dir.create(dummypackage)
22 |
23 | # {fusen} steps
24 | fill_description(pkg = dummypackage, fields = list(Title = "Dummy Package"))
25 | dev_file <- suppressMessages(add_flat_template(pkg = dummypackage, overwrite = TRUE, open = FALSE))
26 | flat_file <- dev_file[grepl("flat_", dev_file)]
27 |
28 | usethis::with_project(dummypackage, {
29 | suppressMessages(
30 | inflate(pkg = dummypackage, flat_file = flat_file,
31 | vignette_name = "Get started", check = FALSE,
32 | open_vignette = FALSE)
33 | )
34 | })
35 |
36 | test_that("inflate() worked correctly", {
37 | # R files
38 | my_median_file <- file.path(dummypackage, "R", "my_median.R")
39 | expect_true(file.exists(my_median_file))
40 | })
41 | ```
42 |
43 |
44 | ### {fusen} : adopt "Rmd-first" method
45 |
46 | - Start with documentation
47 | - Develop everything in a familiar place: the RMarkdown
48 | - {fusen} inflates the package for you
49 |
50 |
51 |
52 | > What if there was a package that could take an Rmd file, kind of like a sheet of paper, and if you follow the right folding, you can blow it up like a package?
53 |
54 | ```{r, echo=FALSE, out.width="80%"}
55 | knitr::include_graphics("images/fusen_fold_inflate.png")
56 | ```
57 |
58 | ---
59 | class: slide
60 | ### [Short version] - Preamble
61 |
62 | - What are the principal components of a package?
63 | - Where do I have to write what?
64 | - How does {fusen} make my life easier?
65 |
66 |
67 |
68 | We suggest you to :
69 |
70 | + Watch your trainers create a package {mytools} by following these short steps, without practicing yourself
71 |
72 | --
73 |
74 | + Redo this package {mytools} on your own in a new project
75 |
76 | --
77 |
78 | We won't explain everything here, but you will see the components of a package and where they fit. For the details, that's the goal of your complete training!
79 |
80 | ---
81 | class: slide
82 | ### [Short] 1: Create a new {fusen} project
83 |
84 | In Rstudio :
85 |
86 | - File > New project > New directory > Package using {fusen}
87 | - Choose the name of the package (explicit, in lower case)
88 | - Name of the package: "mytools"
89 | > _no capital letters, underscores, spaces or special characters_
90 | - Choose the {fusen} template in the dropdown menu: "teaching"
91 |
92 | - Choose the directory where to save the project
93 | - Create the project
94 |
95 | ```{r, echo=FALSE, out.width="40%"}
96 | knitr::include_graphics("images/new_package_fusen_teaching.png")
97 | ```
98 |
99 | ???
100 |
101 | - You are about to build a package. This is a set of tools for testing package structure.
102 | Thus, {mytools}
103 |
104 | - The directory is the "Home" in our platform using `~`
105 |
106 |
107 |
108 | ---
109 | class: slide
110 | ### [Short] 2: Open the {fusen} Rmd flat template
111 |
112 | - The project opens up on a flat template file: "flat_teaching.Rmd"
113 |
114 | --
115 |
116 | - Here are the main components of a package, in a unique Rmd file
117 | + Note the name of the chunks that are required
118 | + The present file is pre-filled with examples
119 |
120 | .pull-left[
121 | ```{r, echo=FALSE, out.width="75%"}
122 | knitr::include_graphics("images/fusen_skeleton_desc.png")
123 | ```
124 | ]
125 |
126 | .pull-right[
127 | ```{r, echo=FALSE, out.width="75%"}
128 | knitr::include_graphics("images/fusen_skeleton_fun.png")
129 | ```
130 | ]
131 |
132 | ???
133 |
134 | You can see that {fusen} opens up the "flat_teaching.Rmd" file in RStudio.
135 | There are a few additional files that we will explore later.
136 | This Rmd file is the "teaching" template with different chunks, which you will not modify this time.
137 |
138 | Let's quickly explore the content of this Rmd. A description, some functions along with examples and tests.
139 | And a final 'development' chunk asking to inflate
140 |
141 | ---
142 | class: slide
143 | ### [Short] 3 : Description
144 |
145 | Describe your future package:
146 |
147 | - Change the name with yours in the `description` chunk
148 | - Execute the complete content of the `description` chunk
149 | + "CTRL + SHIFT + ENTER" should be good
150 | + There are two functions to execute here
151 | - A "DESCRIPTION" file appears with the same information
152 |
153 | --
154 |
155 | #### DESCRIPTION is the first source of documentation for your package
156 |
157 | ```{r, echo=FALSE, out.width="40%"}
158 | knitr::include_graphics("images/fusen_description_file.png")
159 | ```
160 |
161 |
162 | ???
163 |
164 | Yeah, you started with documentation !
165 | There are some more fields in the DESCRIPTION file, but we'll see them later
166 |
167 | ---
168 | class: slide
169 | ### [Short] 4 : Inflate the package
170 |
171 | - Go down the Rmd file and inflate
172 |
173 | ```{r, eval=FALSE}
174 | fusen::inflate(flat_file = "dev/flat_teaching.Rmd")
175 | ```
176 |
177 | ```{r, echo=FALSE, out.width="80%"}
178 | knitr::include_graphics("images/fusen_fold_inflate.png")
179 | ```
180 |
181 | --
182 |
183 | **You built a package!**
184 |
185 | ---
186 | class: slide
187 | ### [Short] 5 : Does it work ?
188 |
189 | - The 'Build' tab should already appear in RStudio
190 | + Otherwise, restart your RStudio session
191 |
192 | - Install the package
193 | + Panel Build > Install and Restart
194 |
195 | - Test the package directly in the console
196 | + `mytools::add_one(value = 56)`
197 |
198 | - Test the knit of the *vignette*
199 | + The vignette is opened "get-started.Rmd"
200 | + Hit the "Knit" button
201 |
202 | - Check that the help for your function appears
203 | + `?add_one`
204 | + Run the reproducible example from help
205 |
206 | ---
207 | class: slide
208 | ### [Short] 5 : Does it work ?
209 |
210 | If you verified everything listed above, your RStudio should look like this
211 |
212 | ```{r, echo=FALSE, out.width="100%"}
213 | knitr::include_graphics("images/fusen_mytools_complete.png")
214 | ```
215 |
216 | ---
217 | class: slide
218 | ### Your turn
219 |
220 | #### Go back to section "[Short] 1" and execute the steps yourself until this slide
221 |
--------------------------------------------------------------------------------
/courses/C01b-package_express_fusen.en.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Package express with {fusen}"
3 | subtitle: "An Rmd is a package"
4 | code: "M13S01C02"
5 | prerequis: ["M13S01C00"]
6 | output:
7 | formation::chapitre: default
8 | xaringan::moon_reader: default
9 | obj_pred: ["get principal components of a package"]
10 | slug: package-express-fusen-en
11 | ---
12 | class: slide
13 |
14 | ```{r include=FALSE}
15 | # Verify {fusen} works here
16 | library(fusen)
17 | library(testthat)
18 |
19 | # Create a new project
20 | dummypackage <- tempfile("inflate.tests")
21 | dir.create(dummypackage)
22 |
23 | # {fusen} steps
24 | fill_description(pkg = dummypackage, fields = list(Title = "Dummy Package"))
25 | dev_file <- suppressMessages(add_flat_template(pkg = dummypackage, overwrite = TRUE, open = FALSE))
26 | flat_file <- dev_file[grepl("flat_", dev_file)]
27 |
28 | usethis::with_project(dummypackage, {
29 | suppressMessages(
30 | inflate(pkg = dummypackage, flat_file = flat_file,
31 | vignette_name = "Get started", check = FALSE,
32 | open_vignette = FALSE)
33 | )
34 | })
35 |
36 | test_that("inflate() worked correctly", {
37 | # R files
38 | my_median_file <- file.path(dummypackage, "R", "my_median.R")
39 | expect_true(file.exists(my_median_file))
40 | })
41 | ```
42 |
43 | ### Preparation: Tools
44 |
45 | To create a package, we will use:
46 |
47 | + RStudio.
48 | + {fusen} package
49 | + the packages {pkgbuild}, {devtools}, {usethis} and {attachment} to save time.
50 | + the {roxygen2} package to generate the documentation.
51 | + the {testthat} package to generate unit tests.
52 | + Rtools.exe (optional and under windows only).
53 |
54 |
55 | ```{r eval = FALSE}
56 | install.packages(c("fusen", "devtools", "usethis", "pkgbuild", "roxygen2", "attachment", "testthat"))
57 | ```
58 |
59 | Rtools is available here: [https://cran.r-project.org/bin/windows/Rtools/](https://cran.r-project.org/bin/windows/Rtools/)
60 | Once (properly) installed `pkgbuild::has_rtools()` should return `TRUE`.
61 | Rtools installs everything needed to compile c++ etc.
62 |
63 | ???
64 |
65 | All of these should be installed on the server already
66 |
67 | ---
68 | class: slide
69 |
70 | ### {fusen}: adopt "Rmd-first" method
71 |
72 | - Start with documentation
73 | - Develop everything in a familiar place: the RMarkdown
74 | - {fusen} inflates the package for you
75 |
76 |
77 |
78 | > What if there was a package that could take an Rmd file, kind of like a sheet of paper, and if you follow the right folding, you can blow it up like a package?
79 |
80 | ```{r, echo=FALSE, out.width="80%"}
81 | knitr::include_graphics("images/fusen_fold_inflate.png")
82 | ```
83 |
84 | ---
85 | class: slide
86 |
87 | ### How {fusen} works?
88 |
89 | - {fusen} copy-pastes in the right place
90 |
91 | ```{r, echo=FALSE, out.width="100%"}
92 | knitr::include_graphics("images/fusen_inflate_functions.png")
93 | ```
94 |
95 | ---
96 | class: slide
97 | ### Longer version - Preamble
98 |
99 | This procedure contains **10 steps**, to be done in order.
100 | Some points are not explained in detail to allow you to obtain a functional R package quickly.
101 |
102 | We suggest you to:
103 |
104 | + Watch your trainers create a package by following these steps, without practicing yourself
105 | --
106 |
107 | + Do this package {hello} on your own in a new project
108 |
109 | --
110 |
111 | > Procedure is split in two parts to let you practice. You will thus have 2 times: "Watch - Do"
112 |
113 | ---
114 | class: slide
115 | ### Step 1: Create a new {fusen} project
116 |
117 | In Rstudio:
118 |
119 | - File > New project > New directory > Package using {fusen}
120 | - Choose the name of the package (explicit, in lower case)
121 | - Name of the package: "hello"
122 | > _no capital letters, underscores, spaces or special characters_
123 | - Choose the {fusen} template in the dropdown menu: "minimal"
124 |
125 | - Choose the directory where to save the project
126 | - Create the project
127 |
128 |
129 | ```{r, echo=FALSE, out.width="30%"}
130 | knitr::include_graphics("images/new_package_fusen_minimal.png")
131 | ```
132 |
133 | > You could also directly run: `fusen::create_fusen(path = "~/hello", template = "minimal")`
134 |
135 | ???
136 |
137 | You are about to build a package. This is a set of tools to be polite with other people, starting by saying hello.
138 | Thus, {hello}
139 |
140 | - The directory is the "Home" in our platform using `~`
141 |
142 | ---
143 | class: slide
144 |
145 | ### Step 2: Open the {fusen} Rmd templates
146 |
147 | This time the template is divided into two flat Rmd files
148 |
149 | - "0-dev_history.Rmd" with the general development commands. In particular the `description` part.
150 | - "flat_minimal.Rmd" with the empty skeleton for creating a function like in the previous "teaching" template
151 |
152 | ```{r, echo=FALSE, out.width="50%"}
153 | knitr::include_graphics("images/flat_minimal_skeleton.png")
154 | ```
155 |
156 | ???
157 |
158 | You can see that {fusen} opens up the "0-dev_history.Rmd" file in RStudio.
159 | There are a few additional files that we will explore later.
160 | This Rmd file is the "minimal" template with different chunks, empty or not empty, that we will fill together in the next steps
161 |
162 | ---
163 | class: slide
164 | ### Step 3: Description
165 |
166 | The description of the package takes place in the first `description` chunk of the "dev_history.Rmd" file
167 |
168 | The first fields to fill in:
169 |
170 | - Title: "Quick Description of the Goal of your Package" (Title Case, no dot at the end)
171 | - Description: "Long description. Sentence case with a dot at the end of the sentences."
172 | - `Authors@R`: vector of one or more `person()`
173 | + `person("Sébastien", "Rochette", email = "sebastien@thinkr.fr", role = c("aut", "cre"))`
174 | - License: The choice of the license
175 |
176 | --
177 |
178 | #### Let's run the content of chunk `description`
179 |
180 | > Observe the content of file "DESCRIPTION" created
181 |
182 | ???
183 |
184 | You are about to build a package, you need to inform the user about its aim. Here, the aim is a set of tools to be polite with other people, starting by saying hello.
185 | You also need to say who you are, so that users know who to call in case of problems.
186 | Finally, the license allows you to say how you want your package to be used and shared. Without license, no one is supposed to use your package.
187 |
188 | Observe the content of DESCRIPTION. Note that what you wrote in the Rmd is now copied in this file, but you did not have to move from your Rmd. So we stay in the Rmd, and we continue the development.
189 |
190 | ---
191 | class: slide
192 |
193 | ### Step 4: Documentation of the package
194 |
195 | A package is created to automate some operations.
196 | Starting with the documentation forces you to think about the structure of the package and the logical sequence of operations.
197 |
198 | - Say what you do in the Rmd text part
199 | - Do what you said in the `function` chunk
200 |
201 | #### Open the "flat_minimal.Rmd" template
202 |
203 | #### Let's run the content of chunk `development`
204 |
205 | ---
206 | class: slide
207 |
208 | ### Step 4: Documentation of the package
209 |
210 | #### Let's see the process of writing a function
211 |
212 |
213 | .pull-left[
214 | ````markdown
215 | ## Say hello to someone
216 |
217 | You can say hello to someone in particular using `say_hello()`.
218 |
219 | ```{r development}`r ''`
220 | library(glue) # On top with others
221 |
222 | message("Hello someone")
223 |
224 | someone <- "Seb"
225 | message(glue("Hello {someone}"))
226 | ```
227 | ````
228 | ]
229 |
230 |
231 | .pull-right[
232 | 1. Describe in words the first operation that the package will have to solve
233 | 2. Define the input data, the possible modifiable parameters, the output result
234 | 3. Write the R code to perform these operations in a `development` chunk
235 | 4. Call necessary packages in a `development` chunk only, at the very beginning, with other `library()` calls
236 | ]
237 |
238 | ???
239 |
240 | Here we take a simple example with a code to say hello. This will be the first tool of our package to be polite with people around us.
241 | Forget that you are about to build a package. Now we develop in a Rmd as usual.
242 | First, we write what we are about to do.
243 | Then, we write some code to say hello. But, I want it to be able to say hello to someone else than me.
244 | So I add a parameter.
245 |
246 | ---
247 | class: slide
248 |
249 | ### Step 5: Embed in a function
250 |
251 | - Move code in the `function` chunk as soon as you transformed it as a function
252 | - Add examples of use in the `examples` chunk
253 |
254 |
255 | ````markdown
256 | ## Say hello to someone
257 |
258 | You can say hello to someone in particular using `say_hello()`.
259 |
260 | ```{r function}`r ''`
261 | say_hello <- function(someone) {
262 | message(glue("Hello {someone}"))
263 | }
264 | ```
265 |
266 | ```{r examples}`r ''`
267 | say_hello(someone = "Seb")
268 | ```
269 | ````
270 |
271 | - Each chunk has a specific task
272 | - Run the chunk `function` to make it available
273 | - Run the function in the `examples` chunk of the Rmd to try it
274 |
275 |
276 | ???
277 |
278 | - Use the code written previously.
279 | - Embed in the `function()` function.
280 | - Use the parameter as a parameter of the function.
281 |
282 | - In the examples chunk, we have a reproducible example.
283 | - We will use it as much as we can
284 | - We use it to illustrate the use of the function.
285 | - You'll see that we will also use it for unit tests. Later.
286 |
287 | ---
288 | class: slide
289 |
290 | ### Step 5: Embed in a function
291 |
292 | The created function can now be documented
293 |
294 | - Add the doc in {roxygen2} format
295 | + `@param` to present the content of inputs
296 | + `@export` for the function to be accessible to the users
297 | + `@importFrom package function` for functions coming from other packages
298 | + `@return` to describe the object that comes out of the function
299 |
300 | - Use RStudio menu: Code > Insert Roxygen Skeleton
301 |
302 | > You must declare the dependencies for the package with `@importFrom`.
303 | The calls to `library()` are only there for development, like a classic Rmd, but are not used by the package when inflated
304 |
305 | ???
306 |
307 | As you just wrote the code of your function, you know exactly
308 |
309 | - what the aim is,
310 | - what are the parameters for,
311 | - what is the output
312 | - what are the dependencies needed
313 |
314 | Write it now. In an hour, you will have forgotten it!
315 |
316 | Note that:
317 |
318 | - because we are in an Rmd, you won't be able to get the auto-completion for roxygen
319 | - because we are in an RStudio Server, the keyboard shortcut for roxygen may be in competition with your browser shortcuts
320 |
321 | Let's see how it looks on the next slide
322 |
323 | ---
324 | class: slide
325 |
326 | ### Step 5: Embed in a function
327 |
328 | - Your "flat_minimal.Rmd" file should look like this:
329 |
330 | ````markdown
331 | ## Say hello to someone
332 |
333 | You can say hello to someone in particular using `say_hello()`.
334 |
335 | ```{r function}`r ''`
336 | #' Show a message in the console to say Hello to someone
337 | #'
338 | #' @param someone Character. Name of the person to say hello to
339 | #' @importFrom glue glue
340 | #' @return Used for side effect. Outputs a message in the console
341 | #' @examples
342 | #' @export
343 |
344 | say_hello <- function(someone) {
345 | message(glue("Hello {someone}"))
346 | }
347 | ```
348 |
349 | ```{r examples}`r ''`
350 | say_hello(someone = "Seb")
351 | ```
352 | ````
353 |
354 | ???
355 |
356 | Here you can see the minimal roxygen content.
357 |
358 | - Title
359 | - Use of param
360 | - importFrom external dependencies
361 | - return an output. This one's special. There is no re-usable output.
362 | - example is in the following chunk. We will let {fusen} deal with this. This is specific to {fusen} to not fill the example here. We'll see this later.
363 | - export the function to let it available to the user when they will call library(your package)
364 | - There may still be a `development` chunk. That's ok.
365 |
366 |
367 | ---
368 | class: slide
369 |
370 | ### Your turn!
371 |
372 | - We are in the half way point of the process
373 | - Got back to Step 1 of this Longer version
374 | - Follow the 5 steps until this slide
375 |
376 | ???
377 |
378 | Tell us in the Chatroom when you are done
379 |
380 | ---
381 | class: slide
382 |
383 | ### Step 6: Write a unit test
384 |
385 | - What do you look for when you run your example?
386 | - What makes you say "it works"?
387 |
388 | #### Write your thoughts into code
389 |
390 | ````markdown
391 | ```{r tests}`r ''`
392 | test_that("say_hello works", {
393 | expect_message(say_hello(someone = "Seb"), "Hello Seb")
394 | })
395 | ```
396 | ````
397 |
398 | ???
399 |
400 | - We use the same exact example to write the unit test directly.
401 | - I won't detail the syntax here, and I won't detail all possible test functions.
402 | - For now, I only want you to have the reflex to do it right after your example, because you already have the test in your mind
403 |
404 | ---
405 | class: slide
406 |
407 | ### Step 7: Inflate the package
408 |
409 | - Let {fusen} inflate the Rmd into a documented and tested package
410 |
411 | ```{r, eval=FALSE}
412 | fusen::inflate(flat_file = "dev/flat_minimal.Rmd", vignette_name = "Say Hello!")
413 | ```
414 |
415 | ```{r, echo=FALSE, out.width="80%"}
416 | knitr::include_graphics("images/fusen_fold_inflate.png")
417 | ```
418 |
419 | > If there are any errors or warnings, read them carrefuly, address them in the "flat_minimal.Rmd" and inflate the package again.
420 |
421 | ???
422 |
423 | - Let {fusen} inflate the Rmd into a package
424 | - There are multiple messages, we do not read all of them.
425 | - We try to address errors at least and re-inflate if needed
426 |
427 | ---
428 | class: slide
429 |
430 | ### Step 8: Explore created folders and files
431 |
432 | - "DESCRIPTION" with dependencies
433 | - "R/" with the function
434 | - "man/" with LateX documentation
435 | - "tests/testthat/" with unit tests
436 | - "vignettes/" with documentation
437 |
438 | ```{r, echo=FALSE, out.width="80%"}
439 | knitr::include_graphics("images/fusen_inflate_functions.png")
440 | ```
441 |
442 |
443 | ---
444 | class: slide
445 |
446 | ### Step 8: Explore created folders and files
447 |
448 | - "DESCRIPTION" with dependencies
449 | - "R/" with the function
450 | - "man/" with LateX documentation
451 | - "tests/testthat/" with unit tests
452 | - "vignettes/" with documentation
453 |
454 | ```{r, echo=FALSE, out.width="80%"}
455 | knitr::include_graphics("images/fusen_inflate_vignette.png")
456 | ```
457 |
458 |
459 | ---
460 | class: slide
461 |
462 | ### Quiz: Find good definitions
463 |
464 | Link files to their description:
465 |
466 | .pull-left[
467 | *Files and folders*
468 |
469 | 1. DESCRIPTION
470 |
471 | 2. dev_history / flat_minimal
472 |
473 | 3. vignettes
474 |
475 | 4. script with roxygen
476 |
477 | 5. testthat
478 |
479 |
480 |
481 |
482 | **Possible answers:**
483 |
484 | - a: ACBDE
485 |
486 | - c: EABCD
487 | ]
488 | .pull-right[
489 | *Documentation*
490 |
491 | A. Development process for developers
492 |
493 | B. Present all the functions of the package and its story
494 |
495 | C. How to use each function (for the user)
496 |
497 | D. Testing the functions for the developers
498 |
499 | E. Content and objectives of the package for all
500 |
501 |
502 |
503 | - b: EDCBA
504 |
505 | - d: BAECD
506 | ]
507 |
508 | ???
509 | - 1E and dependencies for installation
510 | - 2A reusable from one package to another
511 | - 3B with a story
512 | - 4C and build info (@importFrom, @export)
513 | - 5D unit tests
514 |
515 | ---
516 | class: slide
517 |
518 | ### Step 9: Verify again the package
519 |
520 | Generate documentation
521 |
522 | - `attachment::att_amend_desc()`
523 |
524 | Check that the package follows the packages rules
525 |
526 | - `devtools::check()`
527 |
528 | - Solve potential problems in the "flat_minimal.Rmd"
529 | - Re-inflate the package if necessary
530 |
531 | - Reach **0 Error, 0 Warnings, 0 Notes**
532 |
533 | > Store this commands in the "0-dev_history.Rmd" file
534 |
535 |
536 |
537 | > Note that `fusen::inflate()` already launches this two commands, but who knows!
538 |
539 | ???
540 |
541 | It is always good to know these commands, although `inflate()` already does them. You may need them if you go back to a classical way of maintaining your package
542 |
543 | ---
544 | class: slide
545 |
546 | ### Step 10: Install and use your package
547 |
548 | - The 'Build' tab should already appear in RStudio
549 | + Otherwise, restart your RStudio session
550 |
551 | - Note that you can "check" in the 'Build' panel
552 | + Panel "Build" > "Check"
553 |
554 | - Install the package
555 | + Panel "Build" > "Install and Restart
556 |
557 | - Test the package directly in the console
558 | + `hello::say_hello("Toto")`
559 |
560 | - Test the knit of the vignette
561 |
562 | - Check that the help for your function appears
563 | + `?say_hello`
564 | + Run the reproducible example from help
565 |
566 | ---
567 | class: slide
568 |
569 | ### Your turn
570 |
571 | - Go back to step 6 of this Longer version
572 | - Continue development and inflate your package
573 |
574 | > Edit "flat_minimal.Rmd" and re-execute `inflate()` as many times as necessary until everything runs smoothly.
575 |
576 |
577 | ```{r echo=FALSE, out.width="90%"}
578 | knitr::include_graphics("images/fusen_rmd_folds_pkg.png")
579 | ```
580 |
581 |
582 |
583 | > Bonus: If you are motivated, you can start again from the beginning of the 10 steps procedure with a new package name {hello2}
584 |
585 | ---
586 | class: slide
587 |
588 | ### How to add new functionnalities?
589 |
590 | This would require to start over from 'Step 4' to:
591 |
592 | - Upgrade your existing function
593 |
594 | - Add a new function in the current flat template
595 | + New entitled section with `function`, `examples`, `tests`
596 | + Inflate
597 | + Install
598 |
599 | - There is a RStudio _Addin_ to "Add {fusen} chunks"
600 |
601 | --
602 |
603 | - Or create a new flat template using `fusen::add_flat_template("add")` for a new family of functions, thus new vignette
604 |
605 | - There is a RStudio _Addin_ to "Add {fusen} flat template"
606 |
607 | --
608 |
609 | - And `inflate()` this new "flat_additional.Rmd"
610 |
611 | ---
612 | class: slide
613 |
614 | ### And the classical way without {fusen}?
615 |
616 | - You can use the 'Rmd first ' approach writing your code in a Rmarkdown file
617 | + this can directly be your vignette
618 | - Then, you'll need to fill / copy the different files yourself
619 | - "R/"
620 | - "tests/"
621 | - "vignettes/"
622 |
623 |
624 | ---
625 | class: slide
626 |
627 | ### And the classical way without {fusen}?
628 |
629 | - File > New Project > New directory > Package with devtools
630 | - Fill DESCRIPTION file
631 | - Run function for the desired license
632 | + `usethis::use_*_license()`
633 | - Develop in a Rmd
634 | + Either in the sub-directory "dev/" + `usethis::use_build_ignore("dev/")`
635 | + Or, develop in a vignette directly
636 | - Copy/Cut in the correct place
637 | + functions + examples => "R/"
638 | + `usethis::use_r("ma_fonction")`
639 | + tests => "tests/testthat/"
640 | + `usethis::use_testthat()`
641 | + `usethis::use_test("ma_fonction")`
642 | + vignettes => "vignettes/"
643 | + `usethis::use_vignette("Le titre de ma vignette")`
644 | - Generate documentation
645 | + Either `attachment::att_amend_desc()`
646 | + Ou `roxygen2::roxygenise()` + Fill in DESCRIPTION (Suggests, Imports)
647 | - Check the package
648 | + `devtools::check()` => `0 errors, 0 warnings, 0 notes`
649 |
650 | ---
651 | class: slide
652 |
653 | ### And the classical way without {fusen}?
654 |
655 | - You need to fill the different files yourself
656 | - "R/"
657 | - "tests/"
658 | - "vignettes/"
659 |
660 | - While developing you could
661 | - Run an example of your function in "R/" directly with Ctrl + Enter
662 | - Run the unit test by clicking on "Run test"
663 | - Run the vignette if your package is installed
664 |
665 | - Note that you can still do these actions using {fusen} after `inflate()`
666 |
667 | > Be careful, when using {fusen}, if you want to modify some code, go back to the "flat_*.Rmd" and do `inflate()` again
668 |
669 | ???
670 |
671 | Show that we can do it with fusen too as it is a real classical package
672 |
673 | ---
674 | class: slide
675 |
676 | ### Exercise: Take time to finish your drawings
677 |
678 | Where were moved the pieces of code from chunks:
679 |
680 | - `description`?
681 | - `function`?
682 | - `example`?
683 | - `tests`?
684 | - `development`?
685 |
686 | > Verify and update your previous drawings.
687 | > See each thing that {fusen} does for you!
688 |
689 | ???
690 |
691 | - `description`: in DESCRIPTION
692 | - `function`: in the independent .R file with the name of the function
693 | - `example`: in the independent .R file
694 | + in the independent .R file with the function name
695 | + in the thumbnail
696 | - tests`: in the independent tests/testthat folder with the function name
697 | - development`: nowhere. it stays in the development tracking file "dev_history.Rmd
698 |
699 |
--------------------------------------------------------------------------------
/courses/C04-comment_interagir_zoom.en.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "How to interact with Zoom ?"
3 | code: "M01S02C04"
4 | subtitle: "Features"
5 | output: formation::chapitre
6 | prerequis:
7 | chapitre: ["M01S02C01"]
8 | sequence: ["M01S01"]
9 | obj_ped: "communiquer avec nous dans le cadre de la formation avec Zoom"
10 | slug: how-to-interact-with-zoom
11 | ---
12 | class: slide
13 |
14 | ```{r, include = FALSE}
15 | knitr::opts_chunk$set(echo = TRUE,
16 | warning = FALSE,
17 | message = FALSE)
18 | ```
19 |
20 | ### Using Zoom
21 |
22 | ```{r, echo=FALSE, out.width="95%"}
23 | knitr::include_graphics("images/present_zoom.en.png")
24 | ```
25 |
26 | ---
27 | class:slide
28 |
29 | ### Using Zoom
30 |
31 |
32 | Call for help during a breakout rooms session
33 |
34 | ```{r, echo=FALSE, out.width="55%"}
35 | knitr::include_graphics("images/zoom_aide.png")
36 | ```
37 |
38 | ---
39 | class:slide
40 |
41 | ### How to interact?
42 |
43 | - Please mute your microphone during the slides presentations
44 | - You can share your screen during exercises if you are stuck so that we can help you
45 | - Please cut your webcam off to reduce bandwidth use
46 | + Please turn it back on for interaction with trainers.
47 | + To avoid the impression of talking to a wall, trainers can ask 2-3 people to keep their webcam on.
48 |
49 | - In case you feel blocked in full screen mode
50 | + Double click on the full screen should make it come back in a small window.
51 | + If not, press "Esc"
52 | - In case of "loss" of the bar to switch off your micro/webcam
53 | + In full screen mode, it appears at the top of the screen
54 | + Move the mouse over the small green banner with the name of your computer or your name, the menu should appear.
55 |
56 | - Tip
57 | + Hold the space key to temporarily open the microphone.
58 |
59 |
--------------------------------------------------------------------------------
/courses/C05-comment_utiliser_bakacode.en.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "What is Bakacode?"
3 | subtitle: "The ThinkR e-learning platform"
4 | output: formation::chapitre
5 | params:
6 | dataWD: "/mnt/Data/ThinkR/Seafile/Dossier_ThinkR/ressources Formations/support/data"
7 | slug: what-is-bakacode-en
8 | ---
9 | class: slide
10 |
11 | ```{r include=FALSE}
12 | knitr::opts_chunk$set(
13 | cache = FALSE,
14 | message = FALSE,
15 | warning = FALSE,
16 | eval = TRUE,
17 | fig.align = "center"
18 | )
19 |
20 | # pagedown::chrome_print(here::here("courses/M01-presentation/M01S02-a_quelle_sauce_on_va_vous_manger/C05-comment_utiliser_bakacode.html"), here::here("C05-comment_utiliser_bakacode.en.pdf"))
21 |
22 | ```
23 |
24 | ### Take a tour!
25 |
26 | **BakACode** is the home-made [ThinkR](https://rtask.thinkr.fr) e-learning platform
27 |
28 | - Everything you need during the course is available in one place
29 | - The server has all dependencies required for your tutorial
30 | - You can communicate directly with your instructors
31 |
32 |
33 | ```{r, echo=FALSE, out.width="55%"}
34 | knitr::include_graphics("images/bakacode_long_3.png")
35 | ```
36 |
37 | **Please take this tour to get used to the platform**
38 |
39 | ---
40 | class: slide
41 |
42 | ### Take the tour and use it to answer the quiz at the end of the chapter
43 |
44 | - The instructor creates a file named "hello.Rmd" in the "shared/" directory
45 | + You will need it for the quiz
46 |
47 | --
48 |
49 | Now we let you 3 minutes to read the following slides and answer the quiz at the end of this chapter
50 |
51 |
52 | ---
53 | class: slide
54 | ### Connection
55 |
56 | .pull-left[
57 | ```{r, echo=FALSE, out.width="100%"}
58 | knitr::include_graphics("images/baka_login.png")
59 | ```
60 | ]
61 | .pull-right[
62 | #### Connection
63 |
64 | - Use your credentials to connect with username and password
65 | ]
66 |
67 | Connect to
68 |
69 | ---
70 | class: slide
71 | ### Sessions
72 |
73 | .pull-left[
74 | ```{r, echo=FALSE, out.width="100%"}
75 | knitr::include_graphics("images/baka_sessions.png")
76 | ```
77 | ]
78 | .pull-right[
79 | #### Sessions overview
80 |
81 | - View your current and past training sessions
82 |
83 | ]
84 |
85 | ---
86 | class: slide
87 | ### Home page
88 |
89 | .pull-left[
90 | ```{r, echo=FALSE, out.width="100%"}
91 | knitr::include_graphics("images/baka_courses.png")
92 | ```
93 | ]
94 | .pull-right[
95 | #### Learning objectives
96 |
97 | - Learning objectives of the tutorial
98 |
99 | ]
100 |
101 | ---
102 | class: slide
103 | ### Home page
104 |
105 | .pull-left[
106 | ```{r, echo=FALSE, out.width="100%"}
107 | knitr::include_graphics("images/baka_courses.png")
108 | ```
109 | ]
110 | .pull-right[
111 | #### Learning objectives
112 |
113 | - Learning objectives of the tutorial
114 |
115 | #### Sections
116 |
117 | - A box for each section
118 | - Date and description of the section
119 | - Click on the box to show chapters presented
120 |
121 | ]
122 |
123 |
124 | ---
125 | class: slide
126 | ### Home page - launch
127 |
128 | .pull-left[
129 | ```{r, echo=FALSE, out.width="100%"}
130 | knitr::include_graphics("images/baka_courses_launch.png")
131 | ```
132 | ]
133 | .pull-right[
134 | #### Launch tutorial
135 |
136 | - Click on the Launch ("Lancer") button to start the tutorial
137 |
138 | ]
139 |
140 | ---
141 | class: slide
142 |
143 | ### Pratice - presentation
144 |
145 | .pull-left[
146 | ```{r, echo=FALSE, out.width="100%"}
147 | knitr::include_graphics("images/baka_rstudio.png")
148 | ```
149 | ]
150 | .pull-right[
151 | #### Vertical separator
152 |
153 | - Maintain left click on the vertical bar and use the mouse to change left/right windows ratio
154 |
155 | ]
156 |
157 | ---
158 | class: slide
159 |
160 | ### Pratice - presentation
161 |
162 | .pull-left[
163 | ```{r, echo=FALSE, out.width="100%"}
164 | knitr::include_graphics("images/baka_rstudio.png")
165 | ```
166 | ]
167 | .pull-right[
168 | #### Vertical separator
169 |
170 | - Maintain left click on the vertical bar and use the mouse to change left/right windows ratio
171 |
172 | #### Slides
173 |
174 | - Use arrows of your keyboard to go up and down in the slides
175 | - You can copy-paste code parts
176 |
177 | ]
178 |
179 | ---
180 | class: slide
181 |
182 | ### Pratice - presentation
183 |
184 | .pull-left[
185 | ```{r, echo=FALSE, out.width="100%"}
186 | knitr::include_graphics("images/baka_rstudio.png")
187 | ```
188 | ]
189 | .pull-right[
190 | #### Vertical separator
191 |
192 | - Maintain left click on the vertical bar and use the mouse to change left/right windows ratio
193 |
194 | #### Slides
195 |
196 | - Use arrows of your keyboard to go up and down
197 | - You can copy-paste code parts
198 |
199 | #### RStudio server
200 |
201 | - RStudio project opened with your data and Rmd files for exercises
202 | - Be sure to work in a project!
203 | ]
204 |
205 | ---
206 | class: slide
207 |
208 | ### Pratice - search
209 |
210 | .pull-left[
211 | ```{r, echo=FALSE, out.width="100%"}
212 | knitr::include_graphics("images/baka_toc.png")
213 | ```
214 | ]
215 | .pull-right[
216 | #### Search chapter
217 |
218 | - Click on the slides
219 | - Click on the black box in the top right corner to open the table of content
220 | - Choose your chapter
221 | - Click on the black box to quit the table of content and navigate
222 |
223 | ]
224 |
225 | ---
226 | class: slide
227 |
228 | ### Pratice - search
229 |
230 | .pull-left[
231 | ```{r, echo=FALSE, out.width="100%"}
232 | knitr::include_graphics("images/baka_search.png")
233 | ```
234 | ]
235 | .pull-right[
236 | #### Search words
237 |
238 | - Click on the slides
239 | - Use CTRL + F to open the slides search bar or click on the magnifier icon
240 | - Write your word
241 | - Press Enter to find the next occurence of your word
242 | - Use ESC / ECH to quit the search bar and navigate
243 |
244 | ]
245 |
246 | ---
247 | class: slide
248 |
249 | ### Pratice - export
250 |
251 | .pull-left[
252 | ```{r, echo=FALSE, out.width="100%"}
253 | knitr::include_graphics("images/baka_export.png")
254 | ```
255 | ]
256 | .pull-right[
257 | #### Download your files
258 |
259 | - Download files on your computer
260 | - Select one or more files in the file Pane using checkboxes
261 | - Open the 'More' menu
262 | - Choose 'Export'
263 | - 'Download'
264 | ]
265 |
266 | > We recommend that you export your full project at the end of the course
267 |
268 | ---
269 | class: slide
270 |
271 | ### Top menu
272 |
273 | .pull-left[
274 | ```{r, echo=FALSE, out.width="100%"}
275 | knitr::include_graphics("images/baka_rstudio.png")
276 | ```
277 | ]
278 | .pull-right[
279 | #### Home
280 |
281 | - Go back to home page "Accueil"
282 |
283 | ]
284 | ---
285 | class: slide
286 |
287 | ### Top menu
288 |
289 | .pull-left[
290 | ```{r, echo=FALSE, out.width="100%"}
291 | knitr::include_graphics("images/baka_rstudio.png")
292 | ```
293 | ]
294 | .pull-right[
295 | #### Courses
296 |
297 | - Navigate through the list of courses sections available
298 | ]
299 |
300 | ---
301 | class: slide
302 |
303 | ### Top menu
304 |
305 | .pull-left[
306 | ```{r, echo=FALSE, out.width="100%"}
307 | knitr::include_graphics("images/baka_rstudio.png")
308 | ```
309 | ]
310 | .pull-right[
311 | #### RStudio
312 |
313 | - Opens your current RStudio session as full screen in a new tab
314 | - Note that this will close the RStudio session in the "Practice" interface
315 |
316 | ]
317 |
318 | ---
319 | class: slide
320 |
321 | ### Top menu
322 |
323 | .pull-left[
324 | ```{r, echo=FALSE, out.width="100%"}
325 | knitr::include_graphics("images/baka_rstudio.png")
326 | ```
327 | ]
328 | .pull-right[
329 | #### Resources
330 |
331 | - Opens a new tab with R cheatsheets as PDF
332 | - You can open or download them
333 |
334 | ]
335 |
336 | ---
337 | class: slide
338 |
339 | ### Top menu
340 |
341 | .pull-left[
342 | ```{r, echo=FALSE, out.width="100%"}
343 | knitr::include_graphics("images/baka_rstudio.png")
344 | ```
345 | ]
346 | .pull-right[
347 |
348 | #### Disconnect
349 |
350 | - Disconnect from BakACode
351 |
352 | ]
353 |
354 | ---
355 | class: slide
356 |
357 | ## Quiz
358 |
359 | - Can you download the pdf of the courses?
360 | + It is stored in the "pdf/" folder, in the Home directory
361 | + If you loose the connection, at least you have the slides
362 |
363 | - Did you find the "shared/hello.Rmd" file ?
364 | + You can open it and write your name in it.
365 | + Save it quickly as it is shared with other attendees!
366 |
367 | - Can you use the table of content or the search bar to retrieve my email somewhere at the end of the slides?
368 | + Write it in the chat in private, and keep it for yourself, just in case
369 |
370 |
--------------------------------------------------------------------------------
/courses/C06-pkg_avance_test.en.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Test your code"
3 | subtitle: "Do yourself a favor by making the right decisions"
4 | code: "M13S02C06"
5 | output: formation::chapitre
6 | prerequis: ["M06-rbase"]
7 | obj_ped: "savoir mettre en place des tests unitaires"
8 | slug: tester-son-code-en
9 | ---
10 | class: slide
11 |
12 |
13 |
14 | ### Automate the testing of your code
15 |
16 |
17 |
18 | ---
19 | class: slide
20 |
21 | ### Automate the testing of your code
22 |
23 | #### Why automate your code testing?
24 |
25 | + To save time!
26 | + To work peacefully with others
27 | + To be able to transfer the project
28 | + Guarantee the stability of the project
29 |
30 | #### {testthat} runs at each `check()`.
31 |
32 | - Checks that all functions are still doing what they are supposed to do
33 | - {testthat} is integrated to Rstudio and {devtools}
34 | - Tests can be run with `devtools::test()`
35 |
36 | ---
37 | class: slide
38 |
39 | ### Add a new test file
40 |
41 | - Initiate a test file for a specific function: `usethis::use_test("my_function")`
42 | + Creates a "test/testthat/" folder
43 | + Adds {testthat} to the `Suggests` of DESCRIPTION
44 | + Creates "test/testthat.R" (do not touch)
45 | - Create a test file for each function or function family
46 | + Consistent with function script files in "R/"
47 |
48 | --
49 |
50 | > Note that {fusen} will initiate all of these from the `tests` chunks
51 |
52 | ???
53 |
54 | In a regular package, you can add tests manually.
55 | In {fusen}, tests are added in the `tests` chunks
56 |
57 | ---
58 | class: slide
59 |
60 | ### Writing tests
61 |
62 | Each test file is composed of one or multiple sections, with one or multiple tests:
63 |
64 | ```{r eval = FALSE}
65 | test_that("detail serie1", {
66 | test1a
67 | test1b
68 | })
69 |
70 | test_that("detail serie2", {
71 | test2a
72 | test2b
73 | })
74 |
75 | ```
76 |
77 | If `test2b` fails, I will be informed that it is the second test of "detail serie2" in "my_function" file.
78 |
79 | ???
80 |
81 | Note that if a test fails with {fusen}, you had better modify it in the dev_history.Rmd and `inflate()` again
82 |
83 | ---
84 | class: slide
85 |
86 | ### Writing tests
87 |
88 | - Your test functions start with `expect_*(object, expected)`
89 | + `object`: actual output
90 | + `expected`: the expected one.
91 | - If the test fails, the function returns an error
92 | - If the test passes, the function returns nothing
93 |
94 | Several types of tests are possible, including:
95 |
96 | ```{r eval=TRUE, error=TRUE}
97 | library(testthat)
98 |
99 | expect_equal(10, 10)
100 |
101 | a <- sample(1:10, 1)
102 | b <- sample(1:10, 1)
103 | expect_equal(a + b, 200)
104 | ```
105 |
106 | ---
107 | class: slide
108 |
109 | ### Common tests available in {testthat}
110 |
111 |
112 | ```{r eval = FALSE}
113 | # Test using identical
114 | expect_identical()
115 | # Test error management
116 | expect_error()
117 | expect_message()
118 | expect_warning()
119 | # Test character against regular expression
120 | expect_match()
121 | # Test on logical
122 | expect_true()
123 | expect_false()
124 | # Test if object is lower of greater than expected
125 | expect_less_than()
126 | expect_more_than()
127 | # Test the exact length
128 | expect_length()
129 | # Skip a section if server is not available
130 | skip_if_offline()
131 | ```
132 |
133 | ---
134 | class: slide
135 |
136 | ### What kind of tests do I write?
137 |
138 | - Test that function works correctly when inputs are those expected
139 | - Test outputs are correct for a few scenarios of inputs
140 | - Test each scenario that can trigger a specific line of code (like `if()`)
141 | - Test what happens if other formats of inputs are used
142 | + You may need {assertthat} in your original function
143 |
144 | --
145 |
146 | #### Example of test script in a package :
147 |
148 | ```{r eval = FALSE}
149 | test_that("test weighted.mean", {
150 | expect_equal( weighted.mean(1:10, w = rep(1, 10)), 5.5 )
151 | expect_equal( weighted.mean(1:10, w = 1:10), 7 )
152 | })
153 |
154 | test_that("log fails ", {
155 | expect_error( log("a") )
156 | expect_error( log("bonjour") )
157 | })
158 | ```
159 |
160 | ---
161 | class: slide
162 |
163 | ### Quizz: What does this code do?
164 |
165 | - `save_as_csv()` takes a `dataframe` and a `path` as input and save it as csv using the `path`
166 | + It outputs the `path`
167 |
168 | ```{r eval = FALSE}
169 | test_that("test errors save_as_csv", {
170 | data(iris)
171 | expect_error(save_as_csv(iris, "does/not/exists/out.csv"), "does not exist")
172 | expect_error(save_as_csv(iris, "file.R"), "does not have correct output extension")
173 | })
174 |
175 | test_that("test correct save_as_csv", {
176 | data(iris)
177 | expect_is(save_as_csv(iris, "out.csv"), "character")
178 | expect_true(file.exists(save_as_csv(iris, "out.csv")))
179 | expect_equal(iris, read.csv2("out.csv"))
180 | })
181 |
182 | ```
183 |
184 | ???
185 |
186 | Ask 2 different persons to describe the 2 sections
187 |
188 |
189 | ---
190 | class: slide
191 |
192 | ### Run all tests
193 |
194 | ```{r eval=FALSE}
195 | devtools::test()
196 | ```
197 |
198 |
199 | ```{r, echo=FALSE, out.width="35%"}
200 | knitr::include_graphics("images/exemple_test.png")
201 | ```
202 |
203 |
204 | + Each line corresponds to a test file
205 | + Each test is counted as `OK`, `FAIL`, `WARNING`, `SKIP`.
206 | + Each test file is launched in its own environment, so it is necessary to think about loading the necessary libraries and data each time
207 |
208 |
209 |
210 | > Same applies to {fusen}, after `inflate()`, each `test` chunk is run in a separate environment, you need to keep it in mind while writing test chunks
211 |
212 | ???
213 |
214 | - OK when test is good
215 | - FAIL when test fails
216 | - WARNING if a function in the test returned a warning
217 | - SKIP if skip conditions apply
218 |
219 |
220 | ---
221 | class: slide
222 |
223 | ### Quiz: How to test what is supposed to fail?
224 |
225 | - A - `expect_equal()`
226 | - B - `expect_false()`
227 | - C - `expect_error()`
228 | - D - `expect_warning()`
229 |
230 | ???
231 |
232 | - If your function crashes, R returns an error.
233 | You can catch it with `expect_error()` to avoid crashing the test script
234 | and check that in this case, there is an error.
235 | It is best if the error is chosen and made explicit in your function with a `stop()` or with {assertthat} for example
236 |
237 | - Depending on your definition of fail, `expect_warning()` can also be a good answer.
238 | Generally speaking, a warning should be something that the user has to correct in his code. It is good practice to put `stop()` or `message()`, but not `warning()` in your functions.
239 |
240 | ---
241 | class: slide
242 |
243 | ### TD - Exercise 1
244 |
245 | - Create a {mytools} package:
246 |
247 | + A function that returns the first 6 values of a chosen column (as a parameter) from a dataset. The output is a vector.
248 | + `extract_six_from_col(mtcars, "mpg")` works
249 | + `extract_six_from_col(mtcars, "toto")` returns an error
250 | + unit tests for `extract_six_from_col()`
251 |
252 | > Your package must be documented, **tested** and return 0 errors, 0 warnings, and 0 notes
253 |
254 | ---
255 | class: slide
256 |
257 |
258 | ### TD - Exercise 2
259 |
260 | - Add checks to your `say_hello()` function in the {hello} package to ensure that the input variable is a `character`, of size `1`. Stop the function otherwise with `stop()`.
261 | - Provide the message text as a `character` output of the function, reusable for future processing
262 | - Add unit tests to test all possible outputs
263 |
264 | > Your package must be documented, **tested** and return 0 errors, 0 warnings, and 0 notes
265 |
266 | **Bonus**
267 |
268 | - In the {hello} package, create a new function `create_mail_content()` that
269 | + takes a first name, an email address and a password as input
270 | + uses the `say_hello()` function as a sub-function to get the text of "Hello Someone".
271 | + adds mail content after the "hello" formula, saying `remember your mail: xxx@xxx.xx and password zzz`
272 | - Create a reproducible example that takes a dataframe as input with three columns: `firstname`, `email`, `password` and returns a list with content of custom mails
273 | - Test the whole thing!
274 |
275 | > Your package must be documented, **tested** and return 0 errors, 0 warnings, and 0 notes
276 |
277 | ???
278 |
279 | Note that reproducible example with `create_mail_content()` could be transformed as a new function to take the dataframe as input directly.
280 |
281 |
--------------------------------------------------------------------------------
/courses/C09-pkg_avance_data.en.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Include datasets in your package"
3 | subtitle: "What about data?"
4 | code: "M13S02C09"
5 | output: formation::chapitre
6 | prerequis: ["M06-rbase"]
7 | obj_ped: "savoir intégrer des données dans un packages"
8 | slug: encapsuler-donnees-en
9 | ---
10 | class: slide
11 |
12 |
13 | ### Include datasets
14 |
15 | In a package, it can be useful to include data.
16 |
17 | + To demonstrate the use of a function with a relevant example
18 | + To disseminate information
19 |
20 | --
21 |
22 | There are three types of datasets to include, thus three ways to include them into a package.
23 |
24 | 1. A raw data file (xlsx, csv or other), **NOT** available to the end user, but accessible to the developers only, stored in `data-raw/` folder
25 |
26 | --
27 |
28 | 2. An example dataset in `rda` format, to be loaded as is, available to the user, stored in the `data/` folder (such as `iris` or `mtcars` for example)
29 |
30 |
31 | --
32 |
33 | 3. A data file (xlsx, csv or other) not transformed into `rda`, available to the end user, stored in the `inst/` folder
34 |
35 |
36 | ???
37 |
38 | Let's see how and why
39 |
40 | ---
41 | class: slide
42 |
43 | ### 1. Include datasets in `data-raw/`
44 |
45 | #### Internal dataset, accessible to developers only
46 |
47 | - Developers store raw datasets to keep the source of examples close to them
48 | - Users can not access them, there are not installed
49 |
50 | --
51 |
52 | *Steps:*
53 |
54 | - Create folder `data-raw/` at the root of the package using: `usethis::use_data_raw()`
55 | - Insert raw datasets inside
56 | - Use R/Rmd scripts to prepare a cleaner / smaller dataset for future examples
57 |
58 | --
59 |
60 | *Information:*
61 |
62 | - `data-raw` is not installed with the package
63 | + It is not accessible to the user
64 | - Example:
65 |
66 | ???
67 |
68 | - Prepare data that you will need for your reproducible examples
69 | - Keep the original source of your datasets in a safe place
70 | - Note that with {fusen}, you can realise the preparation steps in a `development` chunk.
71 |
72 | ---
73 | class: slide
74 |
75 | ### 2. Include datasets in `data/`
76 |
77 | #### Exported dataset, accessible to the user
78 |
79 | - Developers includes a dataset in the package using: `usethis::use_data(my_dataset)`
80 | - Users load the dataset named `my_dataset` using: `data(my_dataset)`
81 |
82 | --
83 |
84 | *Steps:*
85 |
86 | - Create `data-raw/` to prepare your dataset using: `usethis::use_data_raw("my_dataset")`
87 | - Prepare your dataset as needed for reproducible examples
88 | - Store `my_dataset` as internal data
89 |
90 | ```{r eval = FALSE}
91 | # Read some raw data
92 | # my_data_to_clean <- readr::read_csv("my_raw_data.csv")
93 |
94 | # Or use existing dataset like `diamonds`
95 | my_dataset <- dplyr::slice_sample(diamonds, prop = 0.2)
96 | usethis::use_data(my_dataset, overwrite = TRUE)
97 | ```
98 |
99 | - `overwrite = TRUE` overwrite the dataset if already exists, as for an update
100 | - Have a look at the content of newly created folder `data/`
101 |
102 | ???
103 |
104 | - We use the directory `data-raw` previously created to prepare dataset
105 | - `use_data()` stores the reproducible example at the right place in the right format
106 |
107 | ---
108 | class: slide
109 |
110 | ### 2. Include datasets in `data/`
111 |
112 | #### Exported dataset, accessible to the user
113 |
114 | - Developers includes a dataset in the package using: `usethis::use_data(my_dataset)`
115 | - Users load the dataset named `my_dataset` using: `data(my_dataset)`
116 |
117 |
118 | *Information:*
119 |
120 | - `my_dataset` is accessible to the user after package installation
121 | ```{r, eval=FALSE}
122 | library(mypackage)
123 | data(my_dataset)
124 | ```
125 | - `my_dataset` is stored as `.rda` file, only readable by R, similar to `.RData` files
126 |
127 | ???
128 |
129 | Package needs to be installed to access the dataset
130 |
131 | ---
132 | class: slide
133 |
134 | ### 2. Include datasets in `data/`
135 |
136 | #### Exported dataset, accessible to the user
137 |
138 | - Exported datasets need to be documented, like functions
139 | - by convention the documentation will be written in a file of the form "R/doc_my_dataset.R".
140 | --
141 |
142 | - The following script will automatically build the documentation to be completed:
143 |
144 |
145 | ```{r eval=FALSE}
146 | my_dataset <- dplyr::slice_sample(diamonds, prop = 0.2)
147 | usethis::use_data(my_dataset, overwrite = TRUE)
148 |
149 | cat(sinew::makeOxygen("my_dataset"),
150 | file = "R/doc_my_dataset.R")
151 | rstudioapi::navigateToFile("R/doc_my_dataset.R")
152 | ```
153 |
154 | _à rajouter dans "data-raw/my_dataset.R"_
155 |
156 |
157 | ???
158 |
159 | Documentation is always the key for a correct package.
160 | Check will remind you of missing data documentation.
161 |
162 |
163 | ---
164 | class: slide
165 |
166 | ### 2. Include datasets in `data/`
167 |
168 | #### Exported dataset, accessible to the user
169 |
170 | - Exported datasets need to be documented, like functions
171 |
172 | *Information:*
173 |
174 | 2 main tags:
175 |
176 | - `@format` (required) a summary of the data.
177 | - if `@format` is not specified, then roxygen will edit a standard one.
178 |
179 | - `@source` : the origin of the data, the source.
180 |
181 | We do not `@export` a dataset.
182 |
183 | ---
184 | class: slide
185 |
186 | ### 3. Include datasets in `inst/`
187 |
188 | #### Raw dataset, accessible to the user
189 |
190 | - Developers includes a dataset in the `inst/` folder as is directly
191 | - Users find the dataset using `system.file("my_dataset.csv", package = "mypackage")`
192 |
193 | --
194 |
195 | *Steps*
196 |
197 | - Create `inst/` folder using: `dir.create(here::here("inst"))`
198 | - Add a dataset inside
199 | - Install the package
200 | - Users can access the path of the dataset and read the file as usual
201 |
202 | ```{r, eval=FALSE}
203 | # Store "my_dataset.csv" in "inst/" folder
204 | the_data_path <- system.file("my_dataset.csv", package = "mypackage")
205 | the_data <- readr::read_csv(the_data_path)
206 | ```
207 |
208 | ---
209 | class: slide
210 |
211 | ### 3. Include datasets in `inst/`
212 |
213 | #### Raw dataset, accessible to the user
214 |
215 | - Developers includes a dataset in the `inst/` folder as is directly
216 | - Users find the dataset using `system.file("my_dataset.csv", package = "mypackage")`
217 |
218 |
219 | *Information*
220 |
221 | - Any type of data is allowed
222 | - Use the path for your reproducible examples
223 | - Organise the content of `inst/` as your want
224 |
225 | ???
226 |
227 | - system.file() does not read the dataset, it returns the path to the dataset
228 | - The dataset is only available after installation of the package
229 |
230 | ---
231 | class: slide
232 |
233 | ### Deal with datasets during development
234 |
235 | - Datasets in `data/` or `inst/` are only available after package installation
236 | - Simulate installation using `pkgload::load_all()` during development
237 | + `system.file()` temporarily returns development path (not installed path)
238 |
239 | --
240 |
241 | *Steps*
242 |
243 | - Check your reproducible examples in the Rmd file with package data
244 |
245 | ```{r, eval=FALSE}
246 | # For development only
247 | pkgload::load_all()
248 |
249 | # Same code to add in your `examples` or `tests`
250 | # Can be tested directly during development
251 | the_data_path <- system.file("my_dataset.csv", package = "mypackage")
252 | the_data <- readr::read_csv(the_data_path)
253 | ```
254 |
255 | --
256 |
257 | > Note that `pkgload::load_all()` also loads functions in development, as it simulates a real installation
258 |
259 | ???
260 |
261 |
262 | ---
263 | class: slide
264 |
265 | ### Quizz
266 |
267 | If I want to provide a dataset to the user in any format I want, where do I store it?
268 |
269 | - A: `extdata/`
270 | - B: `inst/`
271 | - C: `data/`
272 | - D: `data-raw/`
273 |
274 |
275 | ---
276 | class: slide
277 |
278 | ### Your turn!
279 |
280 | 1. Look at the instructor demonstration with *Steps*
281 | 2. Do it yourself
282 |
283 | *Steps*
284 |
285 | - Create a new {fusen} project with `full` template
286 | - Run the content of the `description` chunk in the "dev_history.Rmd"
287 | - Uncomment `development` chunk in "Read data" section in the "flat_full.Rmd"
288 | - Play with data in `inst/` during development
289 |
290 | --
291 |
292 | *Bonus*
293 |
294 | - Create function `check_data_integrity()` that reads a dataset like `nyc_squirrels` and check its integrity
295 | + For instance, `primary_fur_color` columns should only contains a unique color, there should not be any `+` sign inside this column
296 | + Stop the function if the integrity is not good
297 | + Return a message if everything is ok
298 | - Create a reproducible example using the dataset saved in `inst/` with `system.file()`
299 | - Create unit tests with reproducible examples where function should fail
300 |
301 | ???
302 |
303 | https://github.com/statnmap/squirrels.fusen/blob/main/dev/dev_history.Rmd
304 |
305 | ```{r function-1, echo=TRUE, eval=FALSE}
306 | #' Check data integrity
307 | #'
308 | #' @param x dataframe with at least columns "lat", "long" and "primary_fur_color"
309 | #'
310 | #' @return Original dataframe if all tests are good. Otherwise stops.
311 | #' @export
312 | check_data_integrity <- function(x) {
313 | # Verify points are in New York around Central Park
314 | all_coords_ok <- all(
315 | c(
316 | min(x[["lat"]]) > 40.76400,
317 | max(x[["lat"]]) < 40.80100,
318 | min(x[["long"]]) > -73.98300,
319 | max(x[["long"]]) < -73.94735
320 | )
321 | )
322 | if (!all_coords_ok) {stop("Not all data are in Central Park")}
323 |
324 | # Verify there is only one color in primary_fur_color.
325 | # A `+` in the column is a sign of multiple colours
326 | if (any(grepl("+", x[["primary_fur_color"]], fixed = TRUE))) {
327 | stop("There are multiple colors in some 'primary_fur_color'")
328 | }
329 |
330 | message("All tests are good !")
331 | }
332 | ```
333 |
334 | ```{r examples-1, echo=TRUE, eval=FALSE}
335 | # A working example
336 | my_data_example <- data.frame(
337 | lat = c(40.77, 40.78),
338 | long = c(-73.95, -73.96),
339 | primary_fur_color = c("grey", "black")
340 | )
341 | check_data_integrity(my_data_example)
342 | ```
343 |
--------------------------------------------------------------------------------
/courses/C13-git_fusen.en.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Versioning a {fusen} package with git"
3 | subtitle: "And the particular case of {fusen}?"
4 | code: "M13S02C13"
5 | output: formation::chapitre
6 | prerequis: [""]
7 | obj_ped: "Know how to version a {fusen} package"
8 | slug: versionner-fusen-git-en
9 | ---
10 | class: slide
11 |
12 | ## Version a {fusen} package
13 |
14 | 2 possibilities:
15 |
16 | - Your {fusen} package has not been created yet, and you want to set up the versioning before starting the developments
17 |
18 | - Your {fusen} package has already been created, and you now want to version it
19 |
20 | ---
21 | class: slide
22 |
23 | ## Versioning a {fusen} package
24 |
25 | #### Case of a new {fusen} package
26 |
27 | - Initialize the empty project on GitLab _(remembering to use the name of your future package as project name)_
28 |
29 | - Get the `https` link to your project by clicking on the `clone` button
30 |
31 | - In RStudio, create the new project File > New Project > Version Control > git and link to the Repository URL
32 |
33 | Initiate your new {fusen} package:
34 |
35 | ```{r, eval=FALSE}
36 | fusen::create_fusen(path = ".",
37 | template = "minimal",
38 | overwrite = TRUE)
39 | ```
40 |
41 | ---
42 | class: slide
43 |
44 | ## Versioning a {fusen} package
45 |
46 | #### Case of a new {fusen} package
47 |
48 | In the *Terminal*,
49 |
50 | + Switch in a new _main_ branch:
51 |
52 | ```{bash eval=FALSE}
53 | git switch -c main
54 | ```
55 |
56 | + Select modified files in your project:
57 |
58 | ```{bash eval=FALSE}
59 | git add .
60 | ```
61 |
62 | + Write a commit (with an explicit message):
63 |
64 | ```{bash eval=FALSE}
65 | git commit -m "Init fusen package"
66 | ```
67 |
68 | + Push your changes back to the remote:
69 |
70 | ```{bash eval=FALSE}
71 | git push -u origin main
72 | ```
73 |
74 | You can now begin your developments.
75 |
76 | ---
77 | class: slide
78 |
79 | ## Versioning a {fusen} package
80 |
81 | #### Case of an existing {fusen} package
82 |
83 | > This procedure can be used for any type of R project, and therefore for any type of package (not only {fusen} packages)
84 |
85 | --
86 |
87 | - Initialize the empty project on GitLab _(remembering to use the name of your package as project name)_
88 |
89 | - Retrieve the `https` link to your project by clicking on the `clone` button
90 |
91 | - Open the RStudio project and run the command `usethis::use_git()` in the console _(the {usethis} package must be installed)_
92 |
93 | - Answer yes to all the questions asked in the console, if relevant. A first "Initial Commit" is done for you.
94 |
95 | - RStudio restarts and git is operational locally
96 |
97 | ???
98 |
99 | ATTENTION
100 | Si vous modifiez cette slide, modifiez aussi M14S01C06 pour git1jour
101 |
102 | ---
103 | class: slide
104 |
105 | ## Versioning a {fusen} package
106 |
107 | #### Case of an existing {fusen} package
108 |
109 | Now you have to link this project to your **`remote`**:
110 |
111 | ```{r eval=FALSE}
112 | usethis::use_git_remote("origin",
113 | url = "https://gitlab.com/my_name/mypackage.git",
114 | overwrite = TRUE)
115 | ```
116 |
117 | In the *Terminal*, type:
118 |
119 | ```
120 | git push -u origin main
121 | ```
122 |
123 | You just added a **`remote`** and made a first **`push`** on the **`main`** branch.
124 |
125 | ???
126 |
127 | ATTENTION
128 | Si vous modifiez cette slide, modifiez aussi M14S01C06 pour git1jour
129 |
130 | ---
131 | class: slide
132 |
133 | ## Exercise
134 |
135 | Set up the _git_ versioning for your `{hello}` package
136 |
--------------------------------------------------------------------------------
/courses/C14-data-analyses-packages.en.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "What about data analyses in a package?"
3 | subtitle: "From Rmd to package to Rmd"
4 | code: ""
5 | prerequis: [""]
6 | output: formation::chapitre
7 | obj_pred: ["use packages for data analyses"]
8 | slug: data-analyses-packages
9 | ---
10 | class: slide
11 |
12 | ## Create shareable reports through packages
13 |
14 | ### Create a package with your functions
15 |
16 | Then, two possible ways to build your analysis reports:
17 |
18 | - Classical package: Use external projects to use your package functions in Rmd reports
19 | - Compendium-like: Include the Rmd reports inside the package development project
20 |
21 | ---
22 | class: slide
23 |
24 | ## A Compendium is like a package
25 |
26 | The compendium logic is to separate code from the report output:
27 |
28 | - One place to store your R scripts in "R/"
29 | - One place to store the Rmarkdown report in "analyses/"
30 |
31 | This is similar to package logic:
32 |
33 | - One place to store R scripts in "R/"
34 | - One place to store Rmarkdown examples of use in "vignettes/"
35 |
36 | ### Let's combine both worlds to benefit from robustness of packages
37 |
38 | ---
39 | class: slide
40 |
41 | ## Combine {fusen} and Compendium structure
42 |
43 | - Create a {fusen} project, versioned with git
44 |
45 | ```{r, eval=FALSE}
46 | # install.packages("fusen")
47 | fusen::create_fusen(template = "full", with_git = TRUE)
48 | ```
49 |
50 | - Add a "reports/" directory that will not interfer with the package
51 |
52 | ```{r, eval=FALSE}
53 | dir.create("reports")
54 | usethis::use_build_ignore("reports")
55 | ```
56 |
57 |
58 | _Note: you can add the Compendium structure in the "reports/" sub-directory, with package {rcompendium}_
59 |
60 | ```{r, eval=FALSE}
61 | # install.packages("rcompendium")
62 | rcompendium::add_compendium("reports")
63 | ```
64 |
65 | ---
66 | class: slide
67 |
68 | ## Combine {fusen} and Compendium structure
69 |
70 | - Add a reduced dataset for the package in "inst/" or "data/"
71 | + Use it for examples, unit tests, documentation
72 |
73 |
74 | - Build your functions in a "flat" file, like any {fusen} package
75 | + Write the content of the vignette as a reduced version of your future report
76 | + Create examples, unit tests, documentation as usual
77 | + Commit regularly
78 |
79 |
80 | - Use the "reports/" directory to store your reports and outputs, while using the functions of your package
81 | + Create a Rmarkdown report using your functions loaded with `library(my.package)`
82 | + Do not forget to install your package prior to building your report
83 |
84 | ---
85 | class: slide
86 |
87 | ## Why would I include my analysis inside my package?
88 |
89 | **Because of:**
90 |
91 | - {rim}: manage R versions
92 | - {renv}: manage R packages versions
93 | - and Docker: manage OS and system dependencies
94 |
95 | ---
96 | class: slide
97 |
98 | ## Why would I include my analysis inside my package?
99 |
100 | - Develop your project in a controled environment, with fixed versions of packages
101 | - Functions, tests and examples are valid for a specific set of packages versions with a specific R version
102 | - Use your functions for your analysis reports with the same working environment
103 | - Use `attachment::create_renv_for_dev()` (>=0.2.5) to build your "renv.lock" file
104 |
105 | - Allow other users to create their analyses in the same environment, by cloning your repository
106 | + Share your work with the world, without bothering about their R installation
107 |
108 | - You can build a Docker container to also fix system dependencies when using your package. {dockerfiler} can help you to set up the container.
109 |
110 | ---
111 | class: slide
112 |
113 | ## Share your work
114 |
115 | - Build and publish your {pkgdown} website to present how to use your package
116 |
117 | ```{r, eval=FALSE}
118 | # Have a proper Readme - Fill and knit
119 | usethis::use_readme_rmd()
120 |
121 | # Allow {pkgdown}
122 | usethis::use_pkgdown()
123 |
124 | # Try it locally
125 | pkgdown::build_site()
126 |
127 | # GitHub
128 | # Add your credentials for GitHub
129 | gitcreds::gitcreds_set()
130 | # Send your project to a new GitHub project
131 | usethis::use_github()
132 |
133 | # Build and publish with GitHub Actions
134 | usethis::use_github_action("pkgdown")
135 |
136 | # Build and publish on GitLab
137 | gitlabr::use_gitlab_ci()
138 | ```
139 |
140 |
--------------------------------------------------------------------------------
/courses/images/00_connection.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/00_connection.png
--------------------------------------------------------------------------------
/courses/images/01_home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/01_home.png
--------------------------------------------------------------------------------
/courses/images/02_chapters.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/02_chapters.png
--------------------------------------------------------------------------------
/courses/images/03_launch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/03_launch.png
--------------------------------------------------------------------------------
/courses/images/04_separator.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/04_separator.png
--------------------------------------------------------------------------------
/courses/images/05_slides.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/05_slides.png
--------------------------------------------------------------------------------
/courses/images/05_slides_overview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/05_slides_overview.png
--------------------------------------------------------------------------------
/courses/images/06_rstudio_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/06_rstudio_right.png
--------------------------------------------------------------------------------
/courses/images/07_export.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/07_export.png
--------------------------------------------------------------------------------
/courses/images/08_back_home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/08_back_home.png
--------------------------------------------------------------------------------
/courses/images/09_back_courses.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/09_back_courses.png
--------------------------------------------------------------------------------
/courses/images/10_rstudio_full.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/10_rstudio_full.png
--------------------------------------------------------------------------------
/courses/images/11_go_to_chat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/11_go_to_chat.png
--------------------------------------------------------------------------------
/courses/images/12_rocket_chat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/12_rocket_chat.png
--------------------------------------------------------------------------------
/courses/images/13_resources.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/13_resources.png
--------------------------------------------------------------------------------
/courses/images/14_disconnect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/14_disconnect.png
--------------------------------------------------------------------------------
/courses/images/almost-package-no-data.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/almost-package-no-data.png
--------------------------------------------------------------------------------
/courses/images/baka_courses.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/baka_courses.png
--------------------------------------------------------------------------------
/courses/images/baka_courses_launch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/baka_courses_launch.png
--------------------------------------------------------------------------------
/courses/images/baka_export.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/baka_export.png
--------------------------------------------------------------------------------
/courses/images/baka_login.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/baka_login.png
--------------------------------------------------------------------------------
/courses/images/baka_rstudio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/baka_rstudio.png
--------------------------------------------------------------------------------
/courses/images/baka_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/baka_search.png
--------------------------------------------------------------------------------
/courses/images/baka_search_slide.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/baka_search_slide.png
--------------------------------------------------------------------------------
/courses/images/baka_sessions.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/baka_sessions.png
--------------------------------------------------------------------------------
/courses/images/baka_toc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/baka_toc.png
--------------------------------------------------------------------------------
/courses/images/bakacode_long_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/bakacode_long_3.png
--------------------------------------------------------------------------------
/courses/images/cruz_classic_fondnoir.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/cruz_classic_fondnoir.png
--------------------------------------------------------------------------------
/courses/images/exemple_test.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/exemple_test.png
--------------------------------------------------------------------------------
/courses/images/flat_minimal_skeleton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/flat_minimal_skeleton.png
--------------------------------------------------------------------------------
/courses/images/fusen-write-package.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/fusen-write-package.png
--------------------------------------------------------------------------------
/courses/images/fusen_description_file.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/fusen_description_file.png
--------------------------------------------------------------------------------
/courses/images/fusen_fold_inflate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/fusen_fold_inflate.png
--------------------------------------------------------------------------------
/courses/images/fusen_inflate_functions.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/fusen_inflate_functions.png
--------------------------------------------------------------------------------
/courses/images/fusen_inflate_vignette.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/fusen_inflate_vignette.png
--------------------------------------------------------------------------------
/courses/images/fusen_mytools_complete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/fusen_mytools_complete.png
--------------------------------------------------------------------------------
/courses/images/fusen_new_project.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/fusen_new_project.png
--------------------------------------------------------------------------------
/courses/images/fusen_rmd_folds_pkg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/fusen_rmd_folds_pkg.png
--------------------------------------------------------------------------------
/courses/images/fusen_skeleton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/fusen_skeleton.png
--------------------------------------------------------------------------------
/courses/images/fusen_skeleton_desc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/fusen_skeleton_desc.png
--------------------------------------------------------------------------------
/courses/images/fusen_skeleton_fun.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/fusen_skeleton_fun.png
--------------------------------------------------------------------------------
/courses/images/fusen_start_hello.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/fusen_start_hello.png
--------------------------------------------------------------------------------
/courses/images/marmot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/marmot.png
--------------------------------------------------------------------------------
/courses/images/new_package_fusen_minimal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/new_package_fusen_minimal.png
--------------------------------------------------------------------------------
/courses/images/new_package_fusen_teaching.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/new_package_fusen_teaching.png
--------------------------------------------------------------------------------
/courses/images/packages-move-function.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/packages-move-function.png
--------------------------------------------------------------------------------
/courses/images/pkg_attachment_badges.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/pkg_attachment_badges.png
--------------------------------------------------------------------------------
/courses/images/pkg_attachment_cran.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/pkg_attachment_cran.png
--------------------------------------------------------------------------------
/courses/images/pkg_attachment_doc_function.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/pkg_attachment_doc_function.png
--------------------------------------------------------------------------------
/courses/images/pkg_attachment_examples.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/pkg_attachment_examples.png
--------------------------------------------------------------------------------
/courses/images/pkg_attachment_index.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/pkg_attachment_index.png
--------------------------------------------------------------------------------
/courses/images/pkg_attachment_vignette.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/pkg_attachment_vignette.png
--------------------------------------------------------------------------------
/courses/images/present_zoom.en.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/present_zoom.en.png
--------------------------------------------------------------------------------
/courses/images/squirrels_inflated.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/squirrels_inflated.png
--------------------------------------------------------------------------------
/courses/images/squirrels_pkgdown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/squirrels_pkgdown.png
--------------------------------------------------------------------------------
/courses/images/squirrels_rmd_html_snapshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/squirrels_rmd_html_snapshot.png
--------------------------------------------------------------------------------
/courses/images/vignette.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/vignette.png
--------------------------------------------------------------------------------
/courses/images/vignette2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/vignette2.png
--------------------------------------------------------------------------------
/courses/images/zoom_aide.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/courses/images/zoom_aide.png
--------------------------------------------------------------------------------
/courses/quizz.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Quizz"
3 | author: "Sébastien Rochette"
4 | date: "29/04/2021"
5 | output: html_document
6 | ---
7 |
8 | ```{r setup, include=FALSE}
9 | knitr::opts_chunk$set(echo = TRUE)
10 | ```
11 |
12 | **Write additionnal quizz here, ready for Slack poll ?**
13 |
14 | ## Quizz
15 |
16 | Diapo 41:
17 |
18 | /poll "What is a vignette?" "A: A website somewhere on Internet" "B: A Sticker you can add on your laptop" "C: A R script with the help of function accessible in the installed package" "D: A html page built from a Rmd file, accessible in the installed package"
19 |
20 |
21 | Diapo 42:
22 |
23 | /poll "Have you already built a package with all these?" "A: Yes, everything. Functions, examples, tests, vignettes" "B: Only part of documentation. Functions, examples, maybe vignettes" "C: Only functions in a R/ directory" "D: No. I never built a package from scratch"
24 |
25 |
26 | Diapo 68:
27 |
28 | /poll "What is the correct order for documentation to be correclty associate to files and folders?" "a: ACBDE" "b: EDCBA" "c: EABCD" "d: BAECD"
29 |
30 | Diapo 87:
31 |
32 | /poll "How to test what is supposed to fail?" "A : expect_equal()" "B : expect_false()" "C : expect_error()" "D : expect_warning()"
33 |
34 | Diapo 98:
35 |
36 | /poll "If I want to provide a dataset to the user in any format I want, where do I store it?" "A: extdata/" "B: inst/" "C: data/" "D: data-raw/"
37 |
38 |
--------------------------------------------------------------------------------
/dev_history.R:
--------------------------------------------------------------------------------
1 | usethis::use_git_ignore("*.html")
2 | usethis::use_git_ignore("*.md")
3 | usethis::use_git_ignore("!README.md")
4 | usethis::use_git_ignore("*_files/")
5 | usethis::use_git_ignore("token.txt")
6 |
7 | # Manage PR
8 | usethis::pr_fetch(1)
9 | usethis::pr_push()
10 |
11 | # Set {renv}
12 | renv::init()
13 | renv::install("git2r")
14 | renv::install("remotes")
15 | options(remotes.git_credentials = git2r::cred_user_pass("gitlab-ci-token", Sys.getenv("FORGE_THINKR_TOKEN")))
16 | options(renv.auth.formation = list(GIT_PAT = Sys.getenv("FORGE_THINKR_TOKEN")))
17 | renv::install("git::https://forge.thinkr.fr/thinkr/thinkrverse/formation")
18 | remotes::install_git("https://forge.thinkr.fr/thinkr/thinkrverse/formation", upgrade = FALSE, git = "git2r")
19 |
20 | tmpform <- tempfile(pattern = "form-")
21 | git2r::clone("https://forge.thinkr.fr/thinkr/thinkrverse/formation", local_path = tmpform,
22 | credentials = git2r::cred_user_pass("gitlab-ci-token", Sys.getenv("GITLAB_THINKR_TOKEN")))
23 | # credentials = git2r::cred_user_pass("gitlab-ci-token", Sys.getenv("GIT_TOKEN")))
24 | remotes::install_local(path = tmpform, upgrade = FALSE, force = TRUE)
25 |
26 | # fusen
27 | remotes::install_github("ThinkR-open/fusen")
28 |
29 | # Description
30 | # _Get all deps to run courses, except old ones -- SUGGESTS --
31 | all_courses <- list.files(here::here("courses"), full.names = TRUE, pattern = "[.]Rmd", recursive = TRUE)
32 | all_deps_courses <- attachment::att_from_rmds(all_courses)
33 | # _Get all deps to run templates_sc -- IMPORTS --
34 | all_compil_to_test <- "compile_course.R"
35 | # Extract all deps
36 | all_deps_compils <- attachment::att_from_rscripts(all_compil_to_test)
37 |
38 | supplements_imports <- c("git2r", "attachment", "testthat", "here", "flextable",
39 | "remotes")
40 |
41 | all_imports <- unique(c(supplements_imports, all_deps_courses))
42 | all_imports <- all_imports[!all_imports == "formation"]
43 | all_deps_compils <- all_deps_compils[!all_deps_compils == "formation"]
44 | # Add to DESCRIPTION
45 | # usethis::use_description()
46 | attachment::att_to_desc_from_is(
47 | imports = all_imports,
48 | suggests = all_deps_compils
49 | )
50 |
51 | custom_packages <- c(
52 | attachment::att_from_description(),
53 | "renv"#,
54 | # "devtools", "roxygen2", "usethis", "pkgload",
55 | # "testthat", "covr", "attachment",
56 | # remotes::install_github("ThinkR-open/checkhelper")
57 | # "pkgdown", "styler", "checkhelper"
58 | )
59 | renv::snapshot(packages = custom_packages)
60 |
61 |
62 |
63 | # Snapshot before push
64 | options(repos = c("CRAN" = "https://packagemanager.rstudio.com/all/__linux__/focal/latest"))
65 | renv::snapshot()
66 |
67 | # Restore after pull
68 | renv::restore()
69 |
70 | # Set Actions
71 | usethis::use_github_action("render-rmarkdown")
72 | # Move course
73 | dir.create("public")
74 | file.copy("les_cours/complet/support", "public", recursive = TRUE)
75 | writeLines("!*.html\n!*.pdf\n!*_files/", "public/support/.gitignore")
76 |
--------------------------------------------------------------------------------
/img/00_connection.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/img/00_connection.png
--------------------------------------------------------------------------------
/img/01_home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/img/01_home.png
--------------------------------------------------------------------------------
/img/02_chapters.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/img/02_chapters.png
--------------------------------------------------------------------------------
/img/03_launch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/img/03_launch.png
--------------------------------------------------------------------------------
/img/04_separator.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/img/04_separator.png
--------------------------------------------------------------------------------
/img/05_slides.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/img/05_slides.png
--------------------------------------------------------------------------------
/img/05_slides_overview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/img/05_slides_overview.png
--------------------------------------------------------------------------------
/img/06_rstudio_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/img/06_rstudio_right.png
--------------------------------------------------------------------------------
/img/07_export.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/img/07_export.png
--------------------------------------------------------------------------------
/img/08_back_home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/img/08_back_home.png
--------------------------------------------------------------------------------
/img/09_back_courses.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/img/09_back_courses.png
--------------------------------------------------------------------------------
/img/10_rstudio_full.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/img/10_rstudio_full.png
--------------------------------------------------------------------------------
/img/11_go_to_chat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/img/11_go_to_chat.png
--------------------------------------------------------------------------------
/img/12_rocket_chat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/img/12_rocket_chat.png
--------------------------------------------------------------------------------
/img/13_resources.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/img/13_resources.png
--------------------------------------------------------------------------------
/img/14_disconnect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/img/14_disconnect.png
--------------------------------------------------------------------------------
/img/cruz_classic_fondnoir.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/img/cruz_classic_fondnoir.png
--------------------------------------------------------------------------------
/img/present_zoom.en.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/statnmap/teach-package-dev-rmdfirst/1d0cc38057a0f6f4f073f075ce220a681892d267/img/present_zoom.en.png
--------------------------------------------------------------------------------
/renv.lock:
--------------------------------------------------------------------------------
1 | {
2 | "R": {
3 | "Version": "4.2.0",
4 | "Repositories": [
5 | {
6 | "Name": "CRAN",
7 | "URL": "https://packagemanager.rstudio.com/all/latest"
8 | }
9 | ]
10 | },
11 | "Packages": {
12 | "BH": {
13 | "Package": "BH",
14 | "Version": "1.78.0-0",
15 | "Source": "Repository",
16 | "Repository": "RSPM",
17 | "Hash": "4e348572ffcaa2fb1e610e7a941f6f3a",
18 | "Requirements": []
19 | },
20 | "DBI": {
21 | "Package": "DBI",
22 | "Version": "1.1.2",
23 | "Source": "Repository",
24 | "Repository": "RSPM",
25 | "Hash": "dcd1743af4336156873e3ce3c950b8b9",
26 | "Requirements": []
27 | },
28 | "MASS": {
29 | "Package": "MASS",
30 | "Version": "7.3-57",
31 | "Source": "Repository",
32 | "Repository": "CRAN",
33 | "Hash": "71476c1d88d1ebdf31580e5a257d5d31",
34 | "Requirements": []
35 | },
36 | "Matrix": {
37 | "Package": "Matrix",
38 | "Version": "1.4-1",
39 | "Source": "Repository",
40 | "Repository": "CRAN",
41 | "Hash": "699c47c606293bdfbc9fd78a93c9c8fe",
42 | "Requirements": [
43 | "lattice"
44 | ]
45 | },
46 | "R6": {
47 | "Package": "R6",
48 | "Version": "2.5.1",
49 | "Source": "Repository",
50 | "Repository": "RSPM",
51 | "Hash": "470851b6d5d0ac559e9d01bb352b4021",
52 | "Requirements": []
53 | },
54 | "RColorBrewer": {
55 | "Package": "RColorBrewer",
56 | "Version": "1.1-3",
57 | "Source": "Repository",
58 | "Repository": "RSPM",
59 | "Hash": "45f0398006e83a5b10b72a90663d8d8c",
60 | "Requirements": []
61 | },
62 | "Rcpp": {
63 | "Package": "Rcpp",
64 | "Version": "1.0.8.3",
65 | "Source": "Repository",
66 | "Repository": "RSPM",
67 | "Hash": "32e79b908fda56ee57fe518a8d37b864",
68 | "Requirements": []
69 | },
70 | "askpass": {
71 | "Package": "askpass",
72 | "Version": "1.1",
73 | "Source": "Repository",
74 | "Repository": "RSPM",
75 | "Hash": "e8a22846fff485f0be3770c2da758713",
76 | "Requirements": [
77 | "sys"
78 | ]
79 | },
80 | "assertthat": {
81 | "Package": "assertthat",
82 | "Version": "0.2.1",
83 | "Source": "Repository",
84 | "Repository": "CRAN",
85 | "Hash": "50c838a310445e954bc13f26f26a6ecf",
86 | "Requirements": []
87 | },
88 | "attachment": {
89 | "Package": "attachment",
90 | "Version": "0.2.4",
91 | "Source": "CRAN",
92 | "Repository": "RSPM",
93 | "RemoteType": "standard",
94 | "RemotePkgRef": "attachment",
95 | "RemoteRef": "attachment",
96 | "RemoteRepos": "https://packagemanager.rstudio.com/cran/__linux__/bionic/2021-12-14",
97 | "RemotePkgPlatform": "source",
98 | "RemoteSha": "0.2.4",
99 | "Hash": "c30d6fbe723eec254196ac30cf8776d1",
100 | "Requirements": [
101 | "desc",
102 | "glue",
103 | "knitr",
104 | "magrittr",
105 | "rmarkdown",
106 | "roxygen2",
107 | "stringr"
108 | ]
109 | },
110 | "backports": {
111 | "Package": "backports",
112 | "Version": "1.4.1",
113 | "Source": "Repository",
114 | "Repository": "RSPM",
115 | "Hash": "c39fbec8a30d23e721980b8afb31984c",
116 | "Requirements": []
117 | },
118 | "base64enc": {
119 | "Package": "base64enc",
120 | "Version": "0.1-3",
121 | "Source": "Repository",
122 | "Repository": "RSPM",
123 | "Hash": "543776ae6848fde2f48ff3816d0628bc",
124 | "Requirements": []
125 | },
126 | "bit": {
127 | "Package": "bit",
128 | "Version": "4.0.4",
129 | "Source": "Repository",
130 | "Repository": "RSPM",
131 | "Hash": "f36715f14d94678eea9933af927bc15d",
132 | "Requirements": []
133 | },
134 | "bit64": {
135 | "Package": "bit64",
136 | "Version": "4.0.5",
137 | "Source": "Repository",
138 | "Repository": "RSPM",
139 | "Hash": "9fe98599ca456d6552421db0d6772d8f",
140 | "Requirements": [
141 | "bit"
142 | ]
143 | },
144 | "blob": {
145 | "Package": "blob",
146 | "Version": "1.2.3",
147 | "Source": "Repository",
148 | "Repository": "RSPM",
149 | "Hash": "10d231579bc9c06ab1c320618808d4ff",
150 | "Requirements": [
151 | "rlang",
152 | "vctrs"
153 | ]
154 | },
155 | "brew": {
156 | "Package": "brew",
157 | "Version": "1.0-7",
158 | "Source": "Repository",
159 | "Repository": "RSPM",
160 | "Hash": "38875ea52350ff4b4c03849fc69736c8",
161 | "Requirements": []
162 | },
163 | "brio": {
164 | "Package": "brio",
165 | "Version": "1.1.3",
166 | "Source": "Repository",
167 | "Repository": "RSPM",
168 | "Hash": "976cf154dfb043c012d87cddd8bca363",
169 | "Requirements": []
170 | },
171 | "broom": {
172 | "Package": "broom",
173 | "Version": "0.8.0",
174 | "Source": "Repository",
175 | "Repository": "RSPM",
176 | "Hash": "fe13cb670e14da57fd7a466578db8ce5",
177 | "Requirements": [
178 | "backports",
179 | "dplyr",
180 | "ellipsis",
181 | "generics",
182 | "ggplot2",
183 | "glue",
184 | "purrr",
185 | "rlang",
186 | "stringr",
187 | "tibble",
188 | "tidyr"
189 | ]
190 | },
191 | "bslib": {
192 | "Package": "bslib",
193 | "Version": "0.3.1",
194 | "Source": "Repository",
195 | "Repository": "RSPM",
196 | "Hash": "56ae7e1987b340186a8a5a157c2ec358",
197 | "Requirements": [
198 | "htmltools",
199 | "jquerylib",
200 | "jsonlite",
201 | "rlang",
202 | "sass"
203 | ]
204 | },
205 | "cachem": {
206 | "Package": "cachem",
207 | "Version": "1.0.6",
208 | "Source": "Repository",
209 | "Repository": "RSPM",
210 | "Hash": "648c5b3d71e6a37e3043617489a0a0e9",
211 | "Requirements": [
212 | "fastmap",
213 | "rlang"
214 | ]
215 | },
216 | "callr": {
217 | "Package": "callr",
218 | "Version": "3.7.0",
219 | "Source": "Repository",
220 | "Repository": "RSPM",
221 | "Hash": "461aa75a11ce2400245190ef5d3995df",
222 | "Requirements": [
223 | "R6",
224 | "processx"
225 | ]
226 | },
227 | "cellranger": {
228 | "Package": "cellranger",
229 | "Version": "1.1.0",
230 | "Source": "Repository",
231 | "Repository": "RSPM",
232 | "Hash": "f61dbaec772ccd2e17705c1e872e9e7c",
233 | "Requirements": [
234 | "rematch",
235 | "tibble"
236 | ]
237 | },
238 | "checkmate": {
239 | "Package": "checkmate",
240 | "Version": "2.1.0",
241 | "Source": "Repository",
242 | "Repository": "RSPM",
243 | "Hash": "147e4db6909d8814bb30f671b49d7e06",
244 | "Requirements": [
245 | "backports"
246 | ]
247 | },
248 | "cli": {
249 | "Package": "cli",
250 | "Version": "3.3.0",
251 | "Source": "Repository",
252 | "Repository": "RSPM",
253 | "Hash": "23abf173c2b783dcc43379ab9bba00ee",
254 | "Requirements": [
255 | "glue"
256 | ]
257 | },
258 | "clipr": {
259 | "Package": "clipr",
260 | "Version": "0.8.0",
261 | "Source": "Repository",
262 | "Repository": "RSPM",
263 | "Hash": "3f038e5ac7f41d4ac41ce658c85e3042",
264 | "Requirements": []
265 | },
266 | "codetools": {
267 | "Package": "codetools",
268 | "Version": "0.2-18",
269 | "Source": "Repository",
270 | "Repository": "CRAN",
271 | "Hash": "019388fc48e48b3da0d3a76ff94608a8",
272 | "Requirements": []
273 | },
274 | "colorspace": {
275 | "Package": "colorspace",
276 | "Version": "2.0-3",
277 | "Source": "CRAN",
278 | "Repository": "RSPM",
279 | "RemoteType": "standard",
280 | "RemotePkgRef": "colorspace",
281 | "RemoteRef": "colorspace",
282 | "RemoteRepos": "https://packagemanager.rstudio.com/all/__linux__/focal/latest",
283 | "RemotePkgPlatform": "source",
284 | "RemoteSha": "2.0-3",
285 | "Hash": "bb4341986bc8b914f0f0acf2e4a3f2f7",
286 | "Requirements": []
287 | },
288 | "commonmark": {
289 | "Package": "commonmark",
290 | "Version": "1.8.0",
291 | "Source": "Repository",
292 | "Repository": "RSPM",
293 | "Hash": "2ba81b120c1655ab696c935ef33ea716",
294 | "Requirements": []
295 | },
296 | "cpp11": {
297 | "Package": "cpp11",
298 | "Version": "0.4.2",
299 | "Source": "Repository",
300 | "Repository": "RSPM",
301 | "Hash": "fa53ce256cd280f468c080a58ea5ba8c",
302 | "Requirements": []
303 | },
304 | "crayon": {
305 | "Package": "crayon",
306 | "Version": "1.5.1",
307 | "Source": "Repository",
308 | "Repository": "RSPM",
309 | "Hash": "8dc45fd8a1ee067a92b85ef274e66d6a",
310 | "Requirements": []
311 | },
312 | "credentials": {
313 | "Package": "credentials",
314 | "Version": "1.3.2",
315 | "Source": "Repository",
316 | "Repository": "RSPM",
317 | "Hash": "93762d0a34d78e6a025efdbfb5c6bb41",
318 | "Requirements": [
319 | "askpass",
320 | "curl",
321 | "jsonlite",
322 | "openssl",
323 | "sys"
324 | ]
325 | },
326 | "curl": {
327 | "Package": "curl",
328 | "Version": "4.3.2",
329 | "Source": "Repository",
330 | "Repository": "RSPM",
331 | "Hash": "022c42d49c28e95d69ca60446dbabf88",
332 | "Requirements": []
333 | },
334 | "data.table": {
335 | "Package": "data.table",
336 | "Version": "1.14.2",
337 | "Source": "Repository",
338 | "Repository": "RSPM",
339 | "Hash": "36b67b5adf57b292923f5659f5f0c853",
340 | "Requirements": []
341 | },
342 | "dbplyr": {
343 | "Package": "dbplyr",
344 | "Version": "2.1.1",
345 | "Source": "Repository",
346 | "Repository": "RSPM",
347 | "Hash": "1f37fa4ab2f5f7eded42f78b9a887182",
348 | "Requirements": [
349 | "DBI",
350 | "R6",
351 | "assertthat",
352 | "blob",
353 | "dplyr",
354 | "ellipsis",
355 | "glue",
356 | "lifecycle",
357 | "magrittr",
358 | "purrr",
359 | "rlang",
360 | "tibble",
361 | "tidyselect",
362 | "vctrs",
363 | "withr"
364 | ]
365 | },
366 | "desc": {
367 | "Package": "desc",
368 | "Version": "1.4.1",
369 | "Source": "Repository",
370 | "Repository": "RSPM",
371 | "Hash": "eebd27ee58fcc58714eedb7aa07d8ad1",
372 | "Requirements": [
373 | "R6",
374 | "cli",
375 | "rprojroot"
376 | ]
377 | },
378 | "devtools": {
379 | "Package": "devtools",
380 | "Version": "2.4.3",
381 | "Source": "Repository",
382 | "Repository": "RSPM",
383 | "Hash": "fc35e13bb582e5fe6f63f3d647a4cbe5",
384 | "Requirements": [
385 | "callr",
386 | "cli",
387 | "desc",
388 | "ellipsis",
389 | "fs",
390 | "httr",
391 | "lifecycle",
392 | "memoise",
393 | "pkgbuild",
394 | "pkgload",
395 | "rcmdcheck",
396 | "remotes",
397 | "rlang",
398 | "roxygen2",
399 | "rstudioapi",
400 | "rversions",
401 | "sessioninfo",
402 | "testthat",
403 | "usethis",
404 | "withr"
405 | ]
406 | },
407 | "diffobj": {
408 | "Package": "diffobj",
409 | "Version": "0.3.5",
410 | "Source": "Repository",
411 | "Repository": "RSPM",
412 | "Hash": "bcaa8b95f8d7d01a5dedfd959ce88ab8",
413 | "Requirements": [
414 | "crayon"
415 | ]
416 | },
417 | "digest": {
418 | "Package": "digest",
419 | "Version": "0.6.29",
420 | "Source": "Repository",
421 | "Repository": "RSPM",
422 | "Hash": "cf6b206a045a684728c3267ef7596190",
423 | "Requirements": []
424 | },
425 | "dplyr": {
426 | "Package": "dplyr",
427 | "Version": "1.0.9",
428 | "Source": "Repository",
429 | "Repository": "RSPM",
430 | "Hash": "f0bda1627a7f5d3f9a0b5add931596ac",
431 | "Requirements": [
432 | "R6",
433 | "generics",
434 | "glue",
435 | "lifecycle",
436 | "magrittr",
437 | "pillar",
438 | "rlang",
439 | "tibble",
440 | "tidyselect",
441 | "vctrs"
442 | ]
443 | },
444 | "dtplyr": {
445 | "Package": "dtplyr",
446 | "Version": "1.2.1",
447 | "Source": "Repository",
448 | "Repository": "RSPM",
449 | "Hash": "f5d195cd5fcc0a77499d9da698ef2ea3",
450 | "Requirements": [
451 | "crayon",
452 | "data.table",
453 | "dplyr",
454 | "ellipsis",
455 | "glue",
456 | "lifecycle",
457 | "rlang",
458 | "tibble",
459 | "tidyselect",
460 | "vctrs"
461 | ]
462 | },
463 | "ellipsis": {
464 | "Package": "ellipsis",
465 | "Version": "0.3.2",
466 | "Source": "Repository",
467 | "Repository": "RSPM",
468 | "Hash": "bb0eec2fe32e88d9e2836c2f73ea2077",
469 | "Requirements": [
470 | "rlang"
471 | ]
472 | },
473 | "evaluate": {
474 | "Package": "evaluate",
475 | "Version": "0.15",
476 | "Source": "Repository",
477 | "Repository": "RSPM",
478 | "Hash": "699a7a93d08c962d9f8950b2d7a227f1",
479 | "Requirements": []
480 | },
481 | "fansi": {
482 | "Package": "fansi",
483 | "Version": "1.0.3",
484 | "Source": "Repository",
485 | "Repository": "RSPM",
486 | "Hash": "83a8afdbe71839506baa9f90eebad7ec",
487 | "Requirements": []
488 | },
489 | "farver": {
490 | "Package": "farver",
491 | "Version": "2.1.0",
492 | "Source": "Repository",
493 | "Repository": "RSPM",
494 | "Hash": "c98eb5133d9cb9e1622b8691487f11bb",
495 | "Requirements": []
496 | },
497 | "fastmap": {
498 | "Package": "fastmap",
499 | "Version": "1.1.0",
500 | "Source": "Repository",
501 | "Repository": "CRAN",
502 | "Hash": "77bd60a6157420d4ffa93b27cf6a58b8",
503 | "Requirements": []
504 | },
505 | "flextable": {
506 | "Package": "flextable",
507 | "Version": "0.7.0",
508 | "Source": "Repository",
509 | "Repository": "RSPM",
510 | "Hash": "c0ab683f6ee8b99be0e0cdce8ad53416",
511 | "Requirements": [
512 | "base64enc",
513 | "data.table",
514 | "gdtools",
515 | "htmltools",
516 | "knitr",
517 | "officer",
518 | "rlang",
519 | "rmarkdown",
520 | "uuid",
521 | "xml2"
522 | ]
523 | },
524 | "forcats": {
525 | "Package": "forcats",
526 | "Version": "0.5.1",
527 | "Source": "Repository",
528 | "Repository": "RSPM",
529 | "Hash": "81c3244cab67468aac4c60550832655d",
530 | "Requirements": [
531 | "ellipsis",
532 | "magrittr",
533 | "rlang",
534 | "tibble"
535 | ]
536 | },
537 | "fs": {
538 | "Package": "fs",
539 | "Version": "1.5.2",
540 | "Source": "Repository",
541 | "Repository": "RSPM",
542 | "Hash": "7c89603d81793f0d5486d91ab1fc6f1d",
543 | "Requirements": []
544 | },
545 | "fusen": {
546 | "Package": "fusen",
547 | "Version": "0.4.0",
548 | "Source": "Repository",
549 | "Repository": "RSPM",
550 | "Hash": "e29366df68d922c4d79605738596b2c1",
551 | "Requirements": [
552 | "attachment",
553 | "cli",
554 | "desc",
555 | "devtools",
556 | "glue",
557 | "here",
558 | "magrittr",
559 | "parsermd",
560 | "roxygen2",
561 | "stringi",
562 | "tibble",
563 | "tidyr",
564 | "usethis"
565 | ]
566 | },
567 | "future": {
568 | "Package": "future",
569 | "Version": "1.25.0",
570 | "Source": "Repository",
571 | "Repository": "RSPM",
572 | "Hash": "877024e372cf61e41f5d13eafd8d4bac",
573 | "Requirements": [
574 | "digest",
575 | "globals",
576 | "listenv",
577 | "parallelly"
578 | ]
579 | },
580 | "gargle": {
581 | "Package": "gargle",
582 | "Version": "1.2.0",
583 | "Source": "Repository",
584 | "Repository": "RSPM",
585 | "Hash": "9d234e6a87a6f8181792de6dc4a00e39",
586 | "Requirements": [
587 | "cli",
588 | "fs",
589 | "glue",
590 | "httr",
591 | "jsonlite",
592 | "rappdirs",
593 | "rlang",
594 | "rstudioapi",
595 | "withr"
596 | ]
597 | },
598 | "gdtools": {
599 | "Package": "gdtools",
600 | "Version": "0.2.4",
601 | "Source": "Repository",
602 | "Repository": "RSPM",
603 | "Hash": "bdfa7431687797edff8c9b0eb9271cc8",
604 | "Requirements": [
605 | "Rcpp",
606 | "systemfonts"
607 | ]
608 | },
609 | "generics": {
610 | "Package": "generics",
611 | "Version": "0.1.2",
612 | "Source": "Repository",
613 | "Repository": "RSPM",
614 | "Hash": "177475892cf4a55865868527654a7741",
615 | "Requirements": []
616 | },
617 | "gert": {
618 | "Package": "gert",
619 | "Version": "1.6.0",
620 | "Source": "Repository",
621 | "Repository": "RSPM",
622 | "Hash": "98c014c4c933f23ea5a0321a4d0b588b",
623 | "Requirements": [
624 | "askpass",
625 | "credentials",
626 | "openssl",
627 | "rstudioapi",
628 | "sys",
629 | "zip"
630 | ]
631 | },
632 | "ggplot2": {
633 | "Package": "ggplot2",
634 | "Version": "3.3.6",
635 | "Source": "CRAN",
636 | "Repository": "CRAN",
637 | "RemoteType": "standard",
638 | "RemotePkgRef": "ggplot2",
639 | "RemoteRef": "ggplot2",
640 | "RemoteRepos": "https://cran.rstudio.com",
641 | "RemotePkgPlatform": "source",
642 | "RemoteSha": "3.3.6",
643 | "Hash": "0fb26d0674c82705c6b701d1a61e02ea",
644 | "Requirements": [
645 | "MASS",
646 | "digest",
647 | "glue",
648 | "gtable",
649 | "isoband",
650 | "mgcv",
651 | "rlang",
652 | "scales",
653 | "tibble",
654 | "withr"
655 | ]
656 | },
657 | "gh": {
658 | "Package": "gh",
659 | "Version": "1.3.0",
660 | "Source": "Repository",
661 | "Repository": "RSPM",
662 | "Hash": "38c2580abbda249bd6afeec00d14f531",
663 | "Requirements": [
664 | "cli",
665 | "gitcreds",
666 | "httr",
667 | "ini",
668 | "jsonlite"
669 | ]
670 | },
671 | "git2r": {
672 | "Package": "git2r",
673 | "Version": "0.30.1",
674 | "Source": "Repository",
675 | "Repository": "RSPM",
676 | "Hash": "e0c6a04a3e7b90e64213d09128f74f1b",
677 | "Requirements": []
678 | },
679 | "gitcreds": {
680 | "Package": "gitcreds",
681 | "Version": "0.1.1",
682 | "Source": "Repository",
683 | "Repository": "CRAN",
684 | "Hash": "f3aefccc1cc50de6338146b62f115de8",
685 | "Requirements": []
686 | },
687 | "globals": {
688 | "Package": "globals",
689 | "Version": "0.15.0",
690 | "Source": "Repository",
691 | "Repository": "RSPM",
692 | "Hash": "ace993e2dad5e64ed46391302b79e94f",
693 | "Requirements": [
694 | "codetools"
695 | ]
696 | },
697 | "glue": {
698 | "Package": "glue",
699 | "Version": "1.6.2",
700 | "Source": "Repository",
701 | "Repository": "RSPM",
702 | "Hash": "4f2596dfb05dac67b9dc558e5c6fba2e",
703 | "Requirements": []
704 | },
705 | "googledrive": {
706 | "Package": "googledrive",
707 | "Version": "2.0.0",
708 | "Source": "Repository",
709 | "Repository": "RSPM",
710 | "Hash": "c3a25adbbfbb03f12e6f88c5fb1f3024",
711 | "Requirements": [
712 | "cli",
713 | "gargle",
714 | "glue",
715 | "httr",
716 | "jsonlite",
717 | "lifecycle",
718 | "magrittr",
719 | "pillar",
720 | "purrr",
721 | "rlang",
722 | "tibble",
723 | "uuid",
724 | "vctrs",
725 | "withr"
726 | ]
727 | },
728 | "googlesheets4": {
729 | "Package": "googlesheets4",
730 | "Version": "1.0.0",
731 | "Source": "Repository",
732 | "Repository": "RSPM",
733 | "Hash": "9a6564184dc4a81daea4f1d7ce357c6a",
734 | "Requirements": [
735 | "cellranger",
736 | "cli",
737 | "curl",
738 | "gargle",
739 | "glue",
740 | "googledrive",
741 | "httr",
742 | "ids",
743 | "magrittr",
744 | "purrr",
745 | "rematch2",
746 | "rlang",
747 | "tibble",
748 | "vctrs"
749 | ]
750 | },
751 | "gtable": {
752 | "Package": "gtable",
753 | "Version": "0.3.0",
754 | "Source": "Repository",
755 | "Repository": "CRAN",
756 | "Hash": "ac5c6baf7822ce8732b343f14c072c4d",
757 | "Requirements": []
758 | },
759 | "haven": {
760 | "Package": "haven",
761 | "Version": "2.5.0",
762 | "Source": "Repository",
763 | "Repository": "RSPM",
764 | "Hash": "e3058e4ac77f4fa686f68a1838d5b715",
765 | "Requirements": [
766 | "cli",
767 | "cpp11",
768 | "forcats",
769 | "hms",
770 | "lifecycle",
771 | "readr",
772 | "rlang",
773 | "tibble",
774 | "tidyselect",
775 | "vctrs"
776 | ]
777 | },
778 | "here": {
779 | "Package": "here",
780 | "Version": "1.0.1",
781 | "Source": "Repository",
782 | "Repository": "RSPM",
783 | "Hash": "24b224366f9c2e7534d2344d10d59211",
784 | "Requirements": [
785 | "rprojroot"
786 | ]
787 | },
788 | "highr": {
789 | "Package": "highr",
790 | "Version": "0.9",
791 | "Source": "Repository",
792 | "Repository": "RSPM",
793 | "Hash": "8eb36c8125038e648e5d111c0d7b2ed4",
794 | "Requirements": [
795 | "xfun"
796 | ]
797 | },
798 | "hms": {
799 | "Package": "hms",
800 | "Version": "1.1.1",
801 | "Source": "Repository",
802 | "Repository": "RSPM",
803 | "Hash": "5b8a2dd0fdbe2ab4f6081e6c7be6dfca",
804 | "Requirements": [
805 | "ellipsis",
806 | "lifecycle",
807 | "pkgconfig",
808 | "rlang",
809 | "vctrs"
810 | ]
811 | },
812 | "htmltools": {
813 | "Package": "htmltools",
814 | "Version": "0.5.2",
815 | "Source": "Repository",
816 | "Repository": "RSPM",
817 | "Hash": "526c484233f42522278ab06fb185cb26",
818 | "Requirements": [
819 | "base64enc",
820 | "digest",
821 | "fastmap",
822 | "rlang"
823 | ]
824 | },
825 | "httpuv": {
826 | "Package": "httpuv",
827 | "Version": "1.6.5",
828 | "Source": "Repository",
829 | "Repository": "RSPM",
830 | "Hash": "97fe71f0a4a1c9890e6c2128afa04bc0",
831 | "Requirements": [
832 | "R6",
833 | "Rcpp",
834 | "later",
835 | "promises"
836 | ]
837 | },
838 | "httr": {
839 | "Package": "httr",
840 | "Version": "1.4.3",
841 | "Source": "Repository",
842 | "Repository": "RSPM",
843 | "Hash": "88d1b310583777edf01ccd1216fb0b2b",
844 | "Requirements": [
845 | "R6",
846 | "curl",
847 | "jsonlite",
848 | "mime",
849 | "openssl"
850 | ]
851 | },
852 | "ids": {
853 | "Package": "ids",
854 | "Version": "1.0.1",
855 | "Source": "Repository",
856 | "Repository": "RSPM",
857 | "Hash": "99df65cfef20e525ed38c3d2577f7190",
858 | "Requirements": [
859 | "openssl",
860 | "uuid"
861 | ]
862 | },
863 | "ini": {
864 | "Package": "ini",
865 | "Version": "0.3.1",
866 | "Source": "Repository",
867 | "Repository": "RSPM",
868 | "Hash": "6154ec2223172bce8162d4153cda21f7",
869 | "Requirements": []
870 | },
871 | "isoband": {
872 | "Package": "isoband",
873 | "Version": "0.2.5",
874 | "Source": "Repository",
875 | "Repository": "RSPM",
876 | "Hash": "7ab57a6de7f48a8dc84910d1eca42883",
877 | "Requirements": []
878 | },
879 | "jquerylib": {
880 | "Package": "jquerylib",
881 | "Version": "0.1.4",
882 | "Source": "Repository",
883 | "Repository": "RSPM",
884 | "Hash": "5aab57a3bd297eee1c1d862735972182",
885 | "Requirements": [
886 | "htmltools"
887 | ]
888 | },
889 | "jsonlite": {
890 | "Package": "jsonlite",
891 | "Version": "1.8.0",
892 | "Source": "Repository",
893 | "Repository": "RSPM",
894 | "Hash": "d07e729b27b372429d42d24d503613a0",
895 | "Requirements": []
896 | },
897 | "knitr": {
898 | "Package": "knitr",
899 | "Version": "1.39",
900 | "Source": "Repository",
901 | "Repository": "RSPM",
902 | "Hash": "029ab7c4badd3cf8af69016b2ba27493",
903 | "Requirements": [
904 | "evaluate",
905 | "highr",
906 | "stringr",
907 | "xfun",
908 | "yaml"
909 | ]
910 | },
911 | "labeling": {
912 | "Package": "labeling",
913 | "Version": "0.4.2",
914 | "Source": "Repository",
915 | "Repository": "RSPM",
916 | "Hash": "3d5108641f47470611a32d0bdf357a72",
917 | "Requirements": []
918 | },
919 | "later": {
920 | "Package": "later",
921 | "Version": "1.3.0",
922 | "Source": "Repository",
923 | "Repository": "RSPM",
924 | "Hash": "7e7b457d7766bc47f2a5f21cc2984f8e",
925 | "Requirements": [
926 | "Rcpp",
927 | "rlang"
928 | ]
929 | },
930 | "lattice": {
931 | "Package": "lattice",
932 | "Version": "0.20-45",
933 | "Source": "Repository",
934 | "Repository": "CRAN",
935 | "Hash": "b64cdbb2b340437c4ee047a1f4c4377b",
936 | "Requirements": []
937 | },
938 | "lifecycle": {
939 | "Package": "lifecycle",
940 | "Version": "1.0.1",
941 | "Source": "Repository",
942 | "Repository": "RSPM",
943 | "Hash": "a6b6d352e3ed897373ab19d8395c98d0",
944 | "Requirements": [
945 | "glue",
946 | "rlang"
947 | ]
948 | },
949 | "listenv": {
950 | "Package": "listenv",
951 | "Version": "0.8.0",
952 | "Source": "Repository",
953 | "Repository": "RSPM",
954 | "Hash": "0bde42ee282efb18c7c4e63822f5b4f7",
955 | "Requirements": []
956 | },
957 | "lubridate": {
958 | "Package": "lubridate",
959 | "Version": "1.8.0",
960 | "Source": "Repository",
961 | "Repository": "RSPM",
962 | "Hash": "2ff5eedb6ee38fb1b81205c73be1be5a",
963 | "Requirements": [
964 | "cpp11",
965 | "generics"
966 | ]
967 | },
968 | "magrittr": {
969 | "Package": "magrittr",
970 | "Version": "2.0.3",
971 | "Source": "Repository",
972 | "Repository": "RSPM",
973 | "Hash": "7ce2733a9826b3aeb1775d56fd305472",
974 | "Requirements": []
975 | },
976 | "memoise": {
977 | "Package": "memoise",
978 | "Version": "2.0.1",
979 | "Source": "Repository",
980 | "Repository": "RSPM",
981 | "Hash": "e2817ccf4a065c5d9d7f2cfbe7c1d78c",
982 | "Requirements": [
983 | "cachem",
984 | "rlang"
985 | ]
986 | },
987 | "mgcv": {
988 | "Package": "mgcv",
989 | "Version": "1.8-40",
990 | "Source": "Repository",
991 | "Repository": "CRAN",
992 | "Hash": "c6b2fdb18cf68ab613bd564363e1ba0d",
993 | "Requirements": [
994 | "Matrix",
995 | "nlme"
996 | ]
997 | },
998 | "mime": {
999 | "Package": "mime",
1000 | "Version": "0.12",
1001 | "Source": "Repository",
1002 | "Repository": "RSPM",
1003 | "Hash": "18e9c28c1d3ca1560ce30658b22ce104",
1004 | "Requirements": []
1005 | },
1006 | "modelr": {
1007 | "Package": "modelr",
1008 | "Version": "0.1.8",
1009 | "Source": "Repository",
1010 | "Repository": "RSPM",
1011 | "Hash": "9fd59716311ee82cba83dc2826fc5577",
1012 | "Requirements": [
1013 | "broom",
1014 | "magrittr",
1015 | "purrr",
1016 | "rlang",
1017 | "tibble",
1018 | "tidyr",
1019 | "tidyselect",
1020 | "vctrs"
1021 | ]
1022 | },
1023 | "munsell": {
1024 | "Package": "munsell",
1025 | "Version": "0.5.0",
1026 | "Source": "Repository",
1027 | "Repository": "CRAN",
1028 | "Hash": "6dfe8bf774944bd5595785e3229d8771",
1029 | "Requirements": [
1030 | "colorspace"
1031 | ]
1032 | },
1033 | "nlme": {
1034 | "Package": "nlme",
1035 | "Version": "3.1-157",
1036 | "Source": "Repository",
1037 | "Repository": "CRAN",
1038 | "Hash": "dbca60742be0c9eddc5205e5c7ca1f44",
1039 | "Requirements": [
1040 | "lattice"
1041 | ]
1042 | },
1043 | "officer": {
1044 | "Package": "officer",
1045 | "Version": "0.4.2",
1046 | "Source": "Repository",
1047 | "Repository": "RSPM",
1048 | "Hash": "d48468bc10938bc5e0c643603b33b29a",
1049 | "Requirements": [
1050 | "R6",
1051 | "uuid",
1052 | "xml2",
1053 | "zip"
1054 | ]
1055 | },
1056 | "openssl": {
1057 | "Package": "openssl",
1058 | "Version": "2.0.0",
1059 | "Source": "Repository",
1060 | "Repository": "RSPM",
1061 | "Hash": "cf4329aac12c2c44089974559c18e446",
1062 | "Requirements": [
1063 | "askpass"
1064 | ]
1065 | },
1066 | "parallelly": {
1067 | "Package": "parallelly",
1068 | "Version": "1.31.1",
1069 | "Source": "Repository",
1070 | "Repository": "RSPM",
1071 | "Hash": "115faaa1a50897c3e2339d1cb7d3d493",
1072 | "Requirements": []
1073 | },
1074 | "parsermd": {
1075 | "Package": "parsermd",
1076 | "Version": "0.1.2",
1077 | "Source": "Repository",
1078 | "Repository": "RSPM",
1079 | "Hash": "c529cbbfcc506e2d8b819676f20c1380",
1080 | "Requirements": [
1081 | "BH",
1082 | "Rcpp",
1083 | "checkmate",
1084 | "cli",
1085 | "dplyr",
1086 | "lifecycle",
1087 | "magrittr",
1088 | "pillar",
1089 | "purrr",
1090 | "readr",
1091 | "rlang",
1092 | "rmarkdown",
1093 | "tibble",
1094 | "tidyr",
1095 | "tidyselect",
1096 | "withr",
1097 | "yaml"
1098 | ]
1099 | },
1100 | "pillar": {
1101 | "Package": "pillar",
1102 | "Version": "1.7.0",
1103 | "Source": "Repository",
1104 | "Repository": "RSPM",
1105 | "Hash": "51dfc97e1b7069e9f7e6f83f3589c22e",
1106 | "Requirements": [
1107 | "cli",
1108 | "crayon",
1109 | "ellipsis",
1110 | "fansi",
1111 | "glue",
1112 | "lifecycle",
1113 | "rlang",
1114 | "utf8",
1115 | "vctrs"
1116 | ]
1117 | },
1118 | "pkgbuild": {
1119 | "Package": "pkgbuild",
1120 | "Version": "1.3.1",
1121 | "Source": "Repository",
1122 | "Repository": "RSPM",
1123 | "Hash": "66d2adfed274daf81ccfe77d974c3b9b",
1124 | "Requirements": [
1125 | "R6",
1126 | "callr",
1127 | "cli",
1128 | "crayon",
1129 | "desc",
1130 | "prettyunits",
1131 | "rprojroot",
1132 | "withr"
1133 | ]
1134 | },
1135 | "pkgconfig": {
1136 | "Package": "pkgconfig",
1137 | "Version": "2.0.3",
1138 | "Source": "Repository",
1139 | "Repository": "RSPM",
1140 | "Hash": "01f28d4278f15c76cddbea05899c5d6f",
1141 | "Requirements": []
1142 | },
1143 | "pkgload": {
1144 | "Package": "pkgload",
1145 | "Version": "1.2.4",
1146 | "Source": "Repository",
1147 | "Repository": "RSPM",
1148 | "Hash": "7533cd805940821bf23eaf3c8d4c1735",
1149 | "Requirements": [
1150 | "cli",
1151 | "crayon",
1152 | "desc",
1153 | "rlang",
1154 | "rprojroot",
1155 | "rstudioapi",
1156 | "withr"
1157 | ]
1158 | },
1159 | "praise": {
1160 | "Package": "praise",
1161 | "Version": "1.0.0",
1162 | "Source": "Repository",
1163 | "Repository": "CRAN",
1164 | "Hash": "a555924add98c99d2f411e37e7d25e9f",
1165 | "Requirements": []
1166 | },
1167 | "prettyunits": {
1168 | "Package": "prettyunits",
1169 | "Version": "1.1.1",
1170 | "Source": "Repository",
1171 | "Repository": "CRAN",
1172 | "Hash": "95ef9167b75dde9d2ccc3c7528393e7e",
1173 | "Requirements": []
1174 | },
1175 | "processx": {
1176 | "Package": "processx",
1177 | "Version": "3.5.3",
1178 | "Source": "Repository",
1179 | "Repository": "RSPM",
1180 | "Hash": "8bbae1a548d0d3fdf6647bdd9d35bf6d",
1181 | "Requirements": [
1182 | "R6",
1183 | "ps"
1184 | ]
1185 | },
1186 | "progress": {
1187 | "Package": "progress",
1188 | "Version": "1.2.2",
1189 | "Source": "Repository",
1190 | "Repository": "RSPM",
1191 | "Hash": "14dc9f7a3c91ebb14ec5bb9208a07061",
1192 | "Requirements": [
1193 | "R6",
1194 | "crayon",
1195 | "hms",
1196 | "prettyunits"
1197 | ]
1198 | },
1199 | "promises": {
1200 | "Package": "promises",
1201 | "Version": "1.2.0.1",
1202 | "Source": "Repository",
1203 | "Repository": "RSPM",
1204 | "Hash": "4ab2c43adb4d4699cf3690acd378d75d",
1205 | "Requirements": [
1206 | "R6",
1207 | "Rcpp",
1208 | "later",
1209 | "magrittr",
1210 | "rlang"
1211 | ]
1212 | },
1213 | "ps": {
1214 | "Package": "ps",
1215 | "Version": "1.7.0",
1216 | "Source": "Repository",
1217 | "Repository": "RSPM",
1218 | "Hash": "eef74b13f32cae6bb0d495e53317c44c",
1219 | "Requirements": []
1220 | },
1221 | "purrr": {
1222 | "Package": "purrr",
1223 | "Version": "0.3.4",
1224 | "Source": "Repository",
1225 | "Repository": "RSPM",
1226 | "Hash": "97def703420c8ab10d8f0e6c72101e02",
1227 | "Requirements": [
1228 | "magrittr",
1229 | "rlang"
1230 | ]
1231 | },
1232 | "rappdirs": {
1233 | "Package": "rappdirs",
1234 | "Version": "0.3.3",
1235 | "Source": "Repository",
1236 | "Repository": "RSPM",
1237 | "Hash": "5e3c5dc0b071b21fa128676560dbe94d",
1238 | "Requirements": []
1239 | },
1240 | "rcmdcheck": {
1241 | "Package": "rcmdcheck",
1242 | "Version": "1.4.0",
1243 | "Source": "Repository",
1244 | "Repository": "RSPM",
1245 | "Hash": "8f25ebe2ec38b1f2aef3b0d2ef76f6c4",
1246 | "Requirements": [
1247 | "R6",
1248 | "callr",
1249 | "cli",
1250 | "curl",
1251 | "desc",
1252 | "digest",
1253 | "pkgbuild",
1254 | "prettyunits",
1255 | "rprojroot",
1256 | "sessioninfo",
1257 | "withr",
1258 | "xopen"
1259 | ]
1260 | },
1261 | "readr": {
1262 | "Package": "readr",
1263 | "Version": "2.1.2",
1264 | "Source": "Repository",
1265 | "Repository": "RSPM",
1266 | "Hash": "9c59de1357dc209868b5feb5c9f0fe2f",
1267 | "Requirements": [
1268 | "R6",
1269 | "cli",
1270 | "clipr",
1271 | "cpp11",
1272 | "crayon",
1273 | "hms",
1274 | "lifecycle",
1275 | "rlang",
1276 | "tibble",
1277 | "tzdb",
1278 | "vroom"
1279 | ]
1280 | },
1281 | "readxl": {
1282 | "Package": "readxl",
1283 | "Version": "1.4.0",
1284 | "Source": "Repository",
1285 | "Repository": "RSPM",
1286 | "Hash": "170c35f745563bb307e963bde0197e4f",
1287 | "Requirements": [
1288 | "cellranger",
1289 | "cpp11",
1290 | "progress",
1291 | "tibble"
1292 | ]
1293 | },
1294 | "rematch": {
1295 | "Package": "rematch",
1296 | "Version": "1.0.1",
1297 | "Source": "Repository",
1298 | "Repository": "CRAN",
1299 | "Hash": "c66b930d20bb6d858cd18e1cebcfae5c",
1300 | "Requirements": []
1301 | },
1302 | "rematch2": {
1303 | "Package": "rematch2",
1304 | "Version": "2.1.2",
1305 | "Source": "Repository",
1306 | "Repository": "RSPM",
1307 | "Hash": "76c9e04c712a05848ae7a23d2f170a40",
1308 | "Requirements": [
1309 | "tibble"
1310 | ]
1311 | },
1312 | "remotes": {
1313 | "Package": "remotes",
1314 | "Version": "2.4.2",
1315 | "Source": "Repository",
1316 | "Repository": "CRAN",
1317 | "Hash": "227045be9aee47e6dda9bb38ac870d67",
1318 | "Requirements": []
1319 | },
1320 | "renv": {
1321 | "Package": "renv",
1322 | "Version": "0.15.4",
1323 | "Source": "Repository",
1324 | "Repository": "CRAN",
1325 | "Hash": "c1078316e1d4f70275fc1ea60c0bc431",
1326 | "Requirements": []
1327 | },
1328 | "reprex": {
1329 | "Package": "reprex",
1330 | "Version": "2.0.1",
1331 | "Source": "Repository",
1332 | "Repository": "RSPM",
1333 | "Hash": "911d101becedc0fde495bd910984bdc8",
1334 | "Requirements": [
1335 | "callr",
1336 | "cli",
1337 | "clipr",
1338 | "fs",
1339 | "glue",
1340 | "knitr",
1341 | "rlang",
1342 | "rmarkdown",
1343 | "rstudioapi",
1344 | "withr"
1345 | ]
1346 | },
1347 | "rlang": {
1348 | "Package": "rlang",
1349 | "Version": "1.0.2",
1350 | "Source": "Repository",
1351 | "Repository": "RSPM",
1352 | "Hash": "04884d9a75d778aca22c7154b8333ec9",
1353 | "Requirements": []
1354 | },
1355 | "rmarkdown": {
1356 | "Package": "rmarkdown",
1357 | "Version": "2.14",
1358 | "Source": "Repository",
1359 | "Repository": "RSPM",
1360 | "Hash": "31b60a882fabfabf6785b8599ffeb8ba",
1361 | "Requirements": [
1362 | "bslib",
1363 | "evaluate",
1364 | "htmltools",
1365 | "jquerylib",
1366 | "jsonlite",
1367 | "knitr",
1368 | "stringr",
1369 | "tinytex",
1370 | "xfun",
1371 | "yaml"
1372 | ]
1373 | },
1374 | "roxygen2": {
1375 | "Package": "roxygen2",
1376 | "Version": "7.1.2",
1377 | "Source": "Repository",
1378 | "Repository": "RSPM",
1379 | "Hash": "eb9849556c4250305106e82edae35b72",
1380 | "Requirements": [
1381 | "R6",
1382 | "brew",
1383 | "commonmark",
1384 | "cpp11",
1385 | "desc",
1386 | "digest",
1387 | "knitr",
1388 | "pkgload",
1389 | "purrr",
1390 | "rlang",
1391 | "stringi",
1392 | "stringr",
1393 | "xml2"
1394 | ]
1395 | },
1396 | "rprojroot": {
1397 | "Package": "rprojroot",
1398 | "Version": "2.0.3",
1399 | "Source": "Repository",
1400 | "Repository": "RSPM",
1401 | "Hash": "1de7ab598047a87bba48434ba35d497d",
1402 | "Requirements": []
1403 | },
1404 | "rstudioapi": {
1405 | "Package": "rstudioapi",
1406 | "Version": "0.13",
1407 | "Source": "Repository",
1408 | "Repository": "CRAN",
1409 | "Hash": "06c85365a03fdaf699966cc1d3cf53ea",
1410 | "Requirements": []
1411 | },
1412 | "rversions": {
1413 | "Package": "rversions",
1414 | "Version": "2.1.1",
1415 | "Source": "Repository",
1416 | "Repository": "RSPM",
1417 | "Hash": "f88fab00907b312f8b23ec13e2d437cb",
1418 | "Requirements": [
1419 | "curl",
1420 | "xml2"
1421 | ]
1422 | },
1423 | "rvest": {
1424 | "Package": "rvest",
1425 | "Version": "1.0.2",
1426 | "Source": "CRAN",
1427 | "Repository": "RSPM",
1428 | "RemoteType": "standard",
1429 | "RemotePkgRef": "rvest",
1430 | "RemoteRef": "rvest",
1431 | "RemoteRepos": "https://packagemanager.rstudio.com/all/__linux__/focal/latest",
1432 | "RemotePkgPlatform": "source",
1433 | "RemoteSha": "1.0.2",
1434 | "Hash": "bb099886deffecd6f9b298b7d4492943",
1435 | "Requirements": [
1436 | "httr",
1437 | "lifecycle",
1438 | "magrittr",
1439 | "rlang",
1440 | "selectr",
1441 | "tibble",
1442 | "xml2"
1443 | ]
1444 | },
1445 | "sass": {
1446 | "Package": "sass",
1447 | "Version": "0.4.1",
1448 | "Source": "Repository",
1449 | "Repository": "RSPM",
1450 | "Hash": "f37c0028d720bab3c513fd65d28c7234",
1451 | "Requirements": [
1452 | "R6",
1453 | "fs",
1454 | "htmltools",
1455 | "rappdirs",
1456 | "rlang"
1457 | ]
1458 | },
1459 | "scales": {
1460 | "Package": "scales",
1461 | "Version": "1.2.0",
1462 | "Source": "Repository",
1463 | "Repository": "RSPM",
1464 | "Hash": "6e8750cdd13477aa440d453da93d5cac",
1465 | "Requirements": [
1466 | "R6",
1467 | "RColorBrewer",
1468 | "farver",
1469 | "labeling",
1470 | "lifecycle",
1471 | "munsell",
1472 | "rlang",
1473 | "viridisLite"
1474 | ]
1475 | },
1476 | "selectr": {
1477 | "Package": "selectr",
1478 | "Version": "0.4-2",
1479 | "Source": "CRAN",
1480 | "Repository": "RSPM",
1481 | "RemoteType": "standard",
1482 | "RemotePkgRef": "selectr",
1483 | "RemoteRef": "selectr",
1484 | "RemoteRepos": "https://packagemanager.rstudio.com/all/__linux__/focal/latest",
1485 | "RemotePkgPlatform": "source",
1486 | "RemoteSha": "0.4-2",
1487 | "Hash": "3838071b66e0c566d55cc26bd6e27bf4",
1488 | "Requirements": [
1489 | "R6",
1490 | "stringr"
1491 | ]
1492 | },
1493 | "servr": {
1494 | "Package": "servr",
1495 | "Version": "0.24",
1496 | "Source": "Repository",
1497 | "Repository": "RSPM",
1498 | "Hash": "e2c3e268d654becf0d78a1ec13a05b46",
1499 | "Requirements": [
1500 | "httpuv",
1501 | "jsonlite",
1502 | "mime",
1503 | "xfun"
1504 | ]
1505 | },
1506 | "sessioninfo": {
1507 | "Package": "sessioninfo",
1508 | "Version": "1.2.2",
1509 | "Source": "Repository",
1510 | "Repository": "RSPM",
1511 | "Hash": "3f9796a8d0a0e8c6eb49a4b029359d1f",
1512 | "Requirements": [
1513 | "cli"
1514 | ]
1515 | },
1516 | "stringi": {
1517 | "Package": "stringi",
1518 | "Version": "1.7.6",
1519 | "Source": "Repository",
1520 | "Repository": "RSPM",
1521 | "Hash": "bba431031d30789535745a9627ac9271",
1522 | "Requirements": []
1523 | },
1524 | "stringr": {
1525 | "Package": "stringr",
1526 | "Version": "1.4.0",
1527 | "Source": "Repository",
1528 | "Repository": "RSPM",
1529 | "Hash": "0759e6b6c0957edb1311028a49a35e76",
1530 | "Requirements": [
1531 | "glue",
1532 | "magrittr",
1533 | "stringi"
1534 | ]
1535 | },
1536 | "sys": {
1537 | "Package": "sys",
1538 | "Version": "3.4",
1539 | "Source": "Repository",
1540 | "Repository": "CRAN",
1541 | "Hash": "b227d13e29222b4574486cfcbde077fa",
1542 | "Requirements": []
1543 | },
1544 | "systemfonts": {
1545 | "Package": "systemfonts",
1546 | "Version": "1.0.4",
1547 | "Source": "Repository",
1548 | "Repository": "RSPM",
1549 | "Hash": "90b28393209827327de889f49935140a",
1550 | "Requirements": [
1551 | "cpp11"
1552 | ]
1553 | },
1554 | "testthat": {
1555 | "Package": "testthat",
1556 | "Version": "3.1.4",
1557 | "Source": "Repository",
1558 | "Repository": "RSPM",
1559 | "Hash": "f76c2a02d0fdc24aa7a47ea34261a6e3",
1560 | "Requirements": [
1561 | "R6",
1562 | "brio",
1563 | "callr",
1564 | "cli",
1565 | "crayon",
1566 | "desc",
1567 | "digest",
1568 | "ellipsis",
1569 | "evaluate",
1570 | "jsonlite",
1571 | "lifecycle",
1572 | "magrittr",
1573 | "pkgload",
1574 | "praise",
1575 | "processx",
1576 | "ps",
1577 | "rlang",
1578 | "waldo",
1579 | "withr"
1580 | ]
1581 | },
1582 | "tibble": {
1583 | "Package": "tibble",
1584 | "Version": "3.1.7",
1585 | "Source": "Repository",
1586 | "Repository": "RSPM",
1587 | "Hash": "08415af406e3dd75049afef9552e7355",
1588 | "Requirements": [
1589 | "ellipsis",
1590 | "fansi",
1591 | "lifecycle",
1592 | "magrittr",
1593 | "pillar",
1594 | "pkgconfig",
1595 | "rlang",
1596 | "vctrs"
1597 | ]
1598 | },
1599 | "tidyr": {
1600 | "Package": "tidyr",
1601 | "Version": "1.2.0",
1602 | "Source": "Repository",
1603 | "Repository": "RSPM",
1604 | "Hash": "d8b95b7fee945d7da6888cf7eb71a49c",
1605 | "Requirements": [
1606 | "cpp11",
1607 | "dplyr",
1608 | "ellipsis",
1609 | "glue",
1610 | "lifecycle",
1611 | "magrittr",
1612 | "purrr",
1613 | "rlang",
1614 | "tibble",
1615 | "tidyselect",
1616 | "vctrs"
1617 | ]
1618 | },
1619 | "tidyselect": {
1620 | "Package": "tidyselect",
1621 | "Version": "1.1.2",
1622 | "Source": "Repository",
1623 | "Repository": "RSPM",
1624 | "Hash": "17f6da8cfd7002760a859915ce7eef8f",
1625 | "Requirements": [
1626 | "ellipsis",
1627 | "glue",
1628 | "purrr",
1629 | "rlang",
1630 | "vctrs"
1631 | ]
1632 | },
1633 | "tidyverse": {
1634 | "Package": "tidyverse",
1635 | "Version": "1.3.1",
1636 | "Source": "Repository",
1637 | "Repository": "RSPM",
1638 | "Hash": "fc4c72b6ae9bb283416bd59a3303bbab",
1639 | "Requirements": [
1640 | "broom",
1641 | "cli",
1642 | "crayon",
1643 | "dbplyr",
1644 | "dplyr",
1645 | "dtplyr",
1646 | "forcats",
1647 | "ggplot2",
1648 | "googledrive",
1649 | "googlesheets4",
1650 | "haven",
1651 | "hms",
1652 | "httr",
1653 | "jsonlite",
1654 | "lubridate",
1655 | "magrittr",
1656 | "modelr",
1657 | "pillar",
1658 | "purrr",
1659 | "readr",
1660 | "readxl",
1661 | "reprex",
1662 | "rlang",
1663 | "rstudioapi",
1664 | "rvest",
1665 | "stringr",
1666 | "tibble",
1667 | "tidyr",
1668 | "xml2"
1669 | ]
1670 | },
1671 | "tinytex": {
1672 | "Package": "tinytex",
1673 | "Version": "0.38",
1674 | "Source": "Repository",
1675 | "Repository": "RSPM",
1676 | "Hash": "759d047596ac173433985deddf313450",
1677 | "Requirements": [
1678 | "xfun"
1679 | ]
1680 | },
1681 | "tzdb": {
1682 | "Package": "tzdb",
1683 | "Version": "0.3.0",
1684 | "Source": "Repository",
1685 | "Repository": "RSPM",
1686 | "Hash": "b2e1cbce7c903eaf23ec05c58e59fb5e",
1687 | "Requirements": [
1688 | "cpp11"
1689 | ]
1690 | },
1691 | "usethis": {
1692 | "Package": "usethis",
1693 | "Version": "2.1.5",
1694 | "Source": "Repository",
1695 | "Repository": "RSPM",
1696 | "Hash": "c499f488e6dd7718accffaee5bc5a79b",
1697 | "Requirements": [
1698 | "cli",
1699 | "clipr",
1700 | "crayon",
1701 | "curl",
1702 | "desc",
1703 | "fs",
1704 | "gert",
1705 | "gh",
1706 | "glue",
1707 | "jsonlite",
1708 | "lifecycle",
1709 | "purrr",
1710 | "rappdirs",
1711 | "rlang",
1712 | "rprojroot",
1713 | "rstudioapi",
1714 | "whisker",
1715 | "withr",
1716 | "yaml"
1717 | ]
1718 | },
1719 | "utf8": {
1720 | "Package": "utf8",
1721 | "Version": "1.2.2",
1722 | "Source": "Repository",
1723 | "Repository": "RSPM",
1724 | "Hash": "c9c462b759a5cc844ae25b5942654d13",
1725 | "Requirements": []
1726 | },
1727 | "uuid": {
1728 | "Package": "uuid",
1729 | "Version": "1.1-0",
1730 | "Source": "Repository",
1731 | "Repository": "RSPM",
1732 | "Hash": "f1cb46c157d080b729159d407be83496",
1733 | "Requirements": []
1734 | },
1735 | "vctrs": {
1736 | "Package": "vctrs",
1737 | "Version": "0.4.1",
1738 | "Source": "Repository",
1739 | "Repository": "RSPM",
1740 | "Hash": "8b54f22e2a58c4f275479c92ce041a57",
1741 | "Requirements": [
1742 | "cli",
1743 | "glue",
1744 | "rlang"
1745 | ]
1746 | },
1747 | "viridisLite": {
1748 | "Package": "viridisLite",
1749 | "Version": "0.4.0",
1750 | "Source": "Repository",
1751 | "Repository": "RSPM",
1752 | "Hash": "55e157e2aa88161bdb0754218470d204",
1753 | "Requirements": []
1754 | },
1755 | "vroom": {
1756 | "Package": "vroom",
1757 | "Version": "1.5.7",
1758 | "Source": "Repository",
1759 | "Repository": "RSPM",
1760 | "Hash": "976507b5a105bc3bdf6a5a5f29e0684f",
1761 | "Requirements": [
1762 | "bit64",
1763 | "cli",
1764 | "cpp11",
1765 | "crayon",
1766 | "glue",
1767 | "hms",
1768 | "lifecycle",
1769 | "progress",
1770 | "rlang",
1771 | "tibble",
1772 | "tidyselect",
1773 | "tzdb",
1774 | "vctrs",
1775 | "withr"
1776 | ]
1777 | },
1778 | "waldo": {
1779 | "Package": "waldo",
1780 | "Version": "0.4.0",
1781 | "Source": "Repository",
1782 | "Repository": "RSPM",
1783 | "Hash": "035fba89d0c86e2113120f93301b98ad",
1784 | "Requirements": [
1785 | "cli",
1786 | "diffobj",
1787 | "fansi",
1788 | "glue",
1789 | "rematch2",
1790 | "rlang",
1791 | "tibble"
1792 | ]
1793 | },
1794 | "whisker": {
1795 | "Package": "whisker",
1796 | "Version": "0.4",
1797 | "Source": "Repository",
1798 | "Repository": "RSPM",
1799 | "Hash": "ca970b96d894e90397ed20637a0c1bbe",
1800 | "Requirements": []
1801 | },
1802 | "withr": {
1803 | "Package": "withr",
1804 | "Version": "2.5.0",
1805 | "Source": "Repository",
1806 | "Repository": "RSPM",
1807 | "Hash": "c0e49a9760983e81e55cdd9be92e7182",
1808 | "Requirements": []
1809 | },
1810 | "xaringan": {
1811 | "Package": "xaringan",
1812 | "Version": "0.24",
1813 | "Source": "Repository",
1814 | "Repository": "RSPM",
1815 | "Hash": "714cfbdbc0775404c8df7894dfed0165",
1816 | "Requirements": [
1817 | "htmltools",
1818 | "knitr",
1819 | "rmarkdown",
1820 | "servr",
1821 | "xfun"
1822 | ]
1823 | },
1824 | "xaringanExtra": {
1825 | "Package": "xaringanExtra",
1826 | "Version": "0.5.5",
1827 | "Source": "GitHub",
1828 | "RemoteType": "github",
1829 | "RemoteHost": "api.github.com",
1830 | "RemoteRepo": "xaringanExtra",
1831 | "RemoteUsername": "gadenbuie",
1832 | "RemoteRef": "HEAD",
1833 | "RemoteSha": "ee5092d2d27bf4b813ea50ec4c264b331283face",
1834 | "Hash": "b58b67af85936c6519f1faa7df5d5149",
1835 | "Requirements": [
1836 | "htmltools",
1837 | "jsonlite",
1838 | "knitr",
1839 | "uuid"
1840 | ]
1841 | },
1842 | "xfun": {
1843 | "Package": "xfun",
1844 | "Version": "0.31",
1845 | "Source": "Repository",
1846 | "Repository": "RSPM",
1847 | "Hash": "a318c6f752b8dcfe9fb74d897418ab2b",
1848 | "Requirements": []
1849 | },
1850 | "xml2": {
1851 | "Package": "xml2",
1852 | "Version": "1.3.3",
1853 | "Source": "Repository",
1854 | "Repository": "RSPM",
1855 | "Hash": "40682ed6a969ea5abfd351eb67833adc",
1856 | "Requirements": []
1857 | },
1858 | "xopen": {
1859 | "Package": "xopen",
1860 | "Version": "1.0.0",
1861 | "Source": "Repository",
1862 | "Repository": "RSPM",
1863 | "Hash": "6c85f015dee9cc7710ddd20f86881f58",
1864 | "Requirements": [
1865 | "processx"
1866 | ]
1867 | },
1868 | "yaml": {
1869 | "Package": "yaml",
1870 | "Version": "2.3.5",
1871 | "Source": "Repository",
1872 | "Repository": "RSPM",
1873 | "Hash": "458bb38374d73bf83b1bb85e353da200",
1874 | "Requirements": []
1875 | },
1876 | "zip": {
1877 | "Package": "zip",
1878 | "Version": "2.2.0",
1879 | "Source": "Repository",
1880 | "Repository": "RSPM",
1881 | "Hash": "c7eef2996ac270a18c2715c997a727c5",
1882 | "Requirements": []
1883 | }
1884 | }
1885 | }
1886 |
--------------------------------------------------------------------------------
/renv/.gitignore:
--------------------------------------------------------------------------------
1 | cellar/
2 | library/
3 | local/
4 | lock/
5 | python/
6 | staging/
7 |
--------------------------------------------------------------------------------
/renv/activate.R:
--------------------------------------------------------------------------------
1 |
2 | local({
3 |
4 | # the requested version of renv
5 | version <- "0.15.4"
6 |
7 | # the project directory
8 | project <- getwd()
9 |
10 | # figure out whether the autoloader is enabled
11 | enabled <- local({
12 |
13 | # first, check config option
14 | override <- getOption("renv.config.autoloader.enabled")
15 | if (!is.null(override))
16 | return(override)
17 |
18 | # next, check environment variables
19 | # TODO: prefer using the configuration one in the future
20 | envvars <- c(
21 | "RENV_CONFIG_AUTOLOADER_ENABLED",
22 | "RENV_AUTOLOADER_ENABLED",
23 | "RENV_ACTIVATE_PROJECT"
24 | )
25 |
26 | for (envvar in envvars) {
27 | envval <- Sys.getenv(envvar, unset = NA)
28 | if (!is.na(envval))
29 | return(tolower(envval) %in% c("true", "t", "1"))
30 | }
31 |
32 | # enable by default
33 | TRUE
34 |
35 | })
36 |
37 | if (!enabled)
38 | return(FALSE)
39 |
40 | # avoid recursion
41 | if (identical(getOption("renv.autoloader.running"), TRUE)) {
42 | warning("ignoring recursive attempt to run renv autoloader")
43 | return(invisible(TRUE))
44 | }
45 |
46 | # signal that we're loading renv during R startup
47 | options(renv.autoloader.running = TRUE)
48 | on.exit(options(renv.autoloader.running = NULL), add = TRUE)
49 |
50 | # signal that we've consented to use renv
51 | options(renv.consent = TRUE)
52 |
53 | # load the 'utils' package eagerly -- this ensures that renv shims, which
54 | # mask 'utils' packages, will come first on the search path
55 | library(utils, lib.loc = .Library)
56 |
57 | # unload renv if it's already been laoded
58 | if ("renv" %in% loadedNamespaces())
59 | unloadNamespace("renv")
60 |
61 | # load bootstrap tools
62 | `%||%` <- function(x, y) {
63 | if (is.environment(x) || length(x)) x else y
64 | }
65 |
66 | bootstrap <- function(version, library) {
67 |
68 | # attempt to download renv
69 | tarball <- tryCatch(renv_bootstrap_download(version), error = identity)
70 | if (inherits(tarball, "error"))
71 | stop("failed to download renv ", version)
72 |
73 | # now attempt to install
74 | status <- tryCatch(renv_bootstrap_install(version, tarball, library), error = identity)
75 | if (inherits(status, "error"))
76 | stop("failed to install renv ", version)
77 |
78 | }
79 |
80 | renv_bootstrap_tests_running <- function() {
81 | getOption("renv.tests.running", default = FALSE)
82 | }
83 |
84 | renv_bootstrap_repos <- function() {
85 |
86 | # check for repos override
87 | repos <- Sys.getenv("RENV_CONFIG_REPOS_OVERRIDE", unset = NA)
88 | if (!is.na(repos))
89 | return(repos)
90 |
91 | # check for lockfile repositories
92 | repos <- tryCatch(renv_bootstrap_repos_lockfile(), error = identity)
93 | if (!inherits(repos, "error") && length(repos))
94 | return(repos)
95 |
96 | # if we're testing, re-use the test repositories
97 | if (renv_bootstrap_tests_running())
98 | return(getOption("renv.tests.repos"))
99 |
100 | # retrieve current repos
101 | repos <- getOption("repos")
102 |
103 | # ensure @CRAN@ entries are resolved
104 | repos[repos == "@CRAN@"] <- getOption(
105 | "renv.repos.cran",
106 | "https://cloud.r-project.org"
107 | )
108 |
109 | # add in renv.bootstrap.repos if set
110 | default <- c(FALLBACK = "https://cloud.r-project.org")
111 | extra <- getOption("renv.bootstrap.repos", default = default)
112 | repos <- c(repos, extra)
113 |
114 | # remove duplicates that might've snuck in
115 | dupes <- duplicated(repos) | duplicated(names(repos))
116 | repos[!dupes]
117 |
118 | }
119 |
120 | renv_bootstrap_repos_lockfile <- function() {
121 |
122 | lockpath <- Sys.getenv("RENV_PATHS_LOCKFILE", unset = "renv.lock")
123 | if (!file.exists(lockpath))
124 | return(NULL)
125 |
126 | lockfile <- tryCatch(renv_json_read(lockpath), error = identity)
127 | if (inherits(lockfile, "error")) {
128 | warning(lockfile)
129 | return(NULL)
130 | }
131 |
132 | repos <- lockfile$R$Repositories
133 | if (length(repos) == 0)
134 | return(NULL)
135 |
136 | keys <- vapply(repos, `[[`, "Name", FUN.VALUE = character(1))
137 | vals <- vapply(repos, `[[`, "URL", FUN.VALUE = character(1))
138 | names(vals) <- keys
139 |
140 | return(vals)
141 |
142 | }
143 |
144 | renv_bootstrap_download <- function(version) {
145 |
146 | # if the renv version number has 4 components, assume it must
147 | # be retrieved via github
148 | nv <- numeric_version(version)
149 | components <- unclass(nv)[[1]]
150 |
151 | # if this appears to be a development version of 'renv', we'll
152 | # try to restore from github
153 | dev <- length(components) == 4L
154 |
155 | # begin collecting different methods for finding renv
156 | methods <- c(
157 | renv_bootstrap_download_tarball,
158 | if (dev)
159 | renv_bootstrap_download_github
160 | else c(
161 | renv_bootstrap_download_cran_latest,
162 | renv_bootstrap_download_cran_archive
163 | )
164 | )
165 |
166 | for (method in methods) {
167 | path <- tryCatch(method(version), error = identity)
168 | if (is.character(path) && file.exists(path))
169 | return(path)
170 | }
171 |
172 | stop("failed to download renv ", version)
173 |
174 | }
175 |
176 | renv_bootstrap_download_impl <- function(url, destfile) {
177 |
178 | mode <- "wb"
179 |
180 | # https://bugs.r-project.org/bugzilla/show_bug.cgi?id=17715
181 | fixup <-
182 | Sys.info()[["sysname"]] == "Windows" &&
183 | substring(url, 1L, 5L) == "file:"
184 |
185 | if (fixup)
186 | mode <- "w+b"
187 |
188 | utils::download.file(
189 | url = url,
190 | destfile = destfile,
191 | mode = mode,
192 | quiet = TRUE
193 | )
194 |
195 | }
196 |
197 | renv_bootstrap_download_cran_latest <- function(version) {
198 |
199 | spec <- renv_bootstrap_download_cran_latest_find(version)
200 |
201 | message("* Downloading renv ", version, " ... ", appendLF = FALSE)
202 |
203 | type <- spec$type
204 | repos <- spec$repos
205 |
206 | info <- tryCatch(
207 | utils::download.packages(
208 | pkgs = "renv",
209 | destdir = tempdir(),
210 | repos = repos,
211 | type = type,
212 | quiet = TRUE
213 | ),
214 | condition = identity
215 | )
216 |
217 | if (inherits(info, "condition")) {
218 | message("FAILED")
219 | return(FALSE)
220 | }
221 |
222 | # report success and return
223 | message("OK (downloaded ", type, ")")
224 | info[1, 2]
225 |
226 | }
227 |
228 | renv_bootstrap_download_cran_latest_find <- function(version) {
229 |
230 | # check whether binaries are supported on this system
231 | binary <-
232 | getOption("renv.bootstrap.binary", default = TRUE) &&
233 | !identical(.Platform$pkgType, "source") &&
234 | !identical(getOption("pkgType"), "source") &&
235 | Sys.info()[["sysname"]] %in% c("Darwin", "Windows")
236 |
237 | types <- c(if (binary) "binary", "source")
238 |
239 | # iterate over types + repositories
240 | for (type in types) {
241 | for (repos in renv_bootstrap_repos()) {
242 |
243 | # retrieve package database
244 | db <- tryCatch(
245 | as.data.frame(
246 | utils::available.packages(type = type, repos = repos),
247 | stringsAsFactors = FALSE
248 | ),
249 | error = identity
250 | )
251 |
252 | if (inherits(db, "error"))
253 | next
254 |
255 | # check for compatible entry
256 | entry <- db[db$Package %in% "renv" & db$Version %in% version, ]
257 | if (nrow(entry) == 0)
258 | next
259 |
260 | # found it; return spec to caller
261 | spec <- list(entry = entry, type = type, repos = repos)
262 | return(spec)
263 |
264 | }
265 | }
266 |
267 | # if we got here, we failed to find renv
268 | fmt <- "renv %s is not available from your declared package repositories"
269 | stop(sprintf(fmt, version))
270 |
271 | }
272 |
273 | renv_bootstrap_download_cran_archive <- function(version) {
274 |
275 | name <- sprintf("renv_%s.tar.gz", version)
276 | repos <- renv_bootstrap_repos()
277 | urls <- file.path(repos, "src/contrib/Archive/renv", name)
278 | destfile <- file.path(tempdir(), name)
279 |
280 | message("* Downloading renv ", version, " ... ", appendLF = FALSE)
281 |
282 | for (url in urls) {
283 |
284 | status <- tryCatch(
285 | renv_bootstrap_download_impl(url, destfile),
286 | condition = identity
287 | )
288 |
289 | if (identical(status, 0L)) {
290 | message("OK")
291 | return(destfile)
292 | }
293 |
294 | }
295 |
296 | message("FAILED")
297 | return(FALSE)
298 |
299 | }
300 |
301 | renv_bootstrap_download_tarball <- function(version) {
302 |
303 | # if the user has provided the path to a tarball via
304 | # an environment variable, then use it
305 | tarball <- Sys.getenv("RENV_BOOTSTRAP_TARBALL", unset = NA)
306 | if (is.na(tarball))
307 | return()
308 |
309 | # allow directories
310 | info <- file.info(tarball, extra_cols = FALSE)
311 | if (identical(info$isdir, TRUE)) {
312 | name <- sprintf("renv_%s.tar.gz", version)
313 | tarball <- file.path(tarball, name)
314 | }
315 |
316 | # bail if it doesn't exist
317 | if (!file.exists(tarball))
318 | return()
319 |
320 | fmt <- "* Bootstrapping with tarball at path '%s'."
321 | msg <- sprintf(fmt, tarball)
322 | message(msg)
323 |
324 | tarball
325 |
326 | }
327 |
328 | renv_bootstrap_download_github <- function(version) {
329 |
330 | enabled <- Sys.getenv("RENV_BOOTSTRAP_FROM_GITHUB", unset = "TRUE")
331 | if (!identical(enabled, "TRUE"))
332 | return(FALSE)
333 |
334 | # prepare download options
335 | pat <- Sys.getenv("GITHUB_PAT")
336 | if (nzchar(Sys.which("curl")) && nzchar(pat)) {
337 | fmt <- "--location --fail --header \"Authorization: token %s\""
338 | extra <- sprintf(fmt, pat)
339 | saved <- options("download.file.method", "download.file.extra")
340 | options(download.file.method = "curl", download.file.extra = extra)
341 | on.exit(do.call(base::options, saved), add = TRUE)
342 | } else if (nzchar(Sys.which("wget")) && nzchar(pat)) {
343 | fmt <- "--header=\"Authorization: token %s\""
344 | extra <- sprintf(fmt, pat)
345 | saved <- options("download.file.method", "download.file.extra")
346 | options(download.file.method = "wget", download.file.extra = extra)
347 | on.exit(do.call(base::options, saved), add = TRUE)
348 | }
349 |
350 | message("* Downloading renv ", version, " from GitHub ... ", appendLF = FALSE)
351 |
352 | url <- file.path("https://api.github.com/repos/rstudio/renv/tarball", version)
353 | name <- sprintf("renv_%s.tar.gz", version)
354 | destfile <- file.path(tempdir(), name)
355 |
356 | status <- tryCatch(
357 | renv_bootstrap_download_impl(url, destfile),
358 | condition = identity
359 | )
360 |
361 | if (!identical(status, 0L)) {
362 | message("FAILED")
363 | return(FALSE)
364 | }
365 |
366 | message("OK")
367 | return(destfile)
368 |
369 | }
370 |
371 | renv_bootstrap_install <- function(version, tarball, library) {
372 |
373 | # attempt to install it into project library
374 | message("* Installing renv ", version, " ... ", appendLF = FALSE)
375 | dir.create(library, showWarnings = FALSE, recursive = TRUE)
376 |
377 | # invoke using system2 so we can capture and report output
378 | bin <- R.home("bin")
379 | exe <- if (Sys.info()[["sysname"]] == "Windows") "R.exe" else "R"
380 | r <- file.path(bin, exe)
381 |
382 | args <- c(
383 | "--vanilla", "CMD", "INSTALL", "--no-multiarch",
384 | "-l", shQuote(path.expand(library)),
385 | shQuote(path.expand(tarball))
386 | )
387 |
388 | output <- system2(r, args, stdout = TRUE, stderr = TRUE)
389 | message("Done!")
390 |
391 | # check for successful install
392 | status <- attr(output, "status")
393 | if (is.numeric(status) && !identical(status, 0L)) {
394 | header <- "Error installing renv:"
395 | lines <- paste(rep.int("=", nchar(header)), collapse = "")
396 | text <- c(header, lines, output)
397 | writeLines(text, con = stderr())
398 | }
399 |
400 | status
401 |
402 | }
403 |
404 | renv_bootstrap_platform_prefix <- function() {
405 |
406 | # construct version prefix
407 | version <- paste(R.version$major, R.version$minor, sep = ".")
408 | prefix <- paste("R", numeric_version(version)[1, 1:2], sep = "-")
409 |
410 | # include SVN revision for development versions of R
411 | # (to avoid sharing platform-specific artefacts with released versions of R)
412 | devel <-
413 | identical(R.version[["status"]], "Under development (unstable)") ||
414 | identical(R.version[["nickname"]], "Unsuffered Consequences")
415 |
416 | if (devel)
417 | prefix <- paste(prefix, R.version[["svn rev"]], sep = "-r")
418 |
419 | # build list of path components
420 | components <- c(prefix, R.version$platform)
421 |
422 | # include prefix if provided by user
423 | prefix <- renv_bootstrap_platform_prefix_impl()
424 | if (!is.na(prefix) && nzchar(prefix))
425 | components <- c(prefix, components)
426 |
427 | # build prefix
428 | paste(components, collapse = "/")
429 |
430 | }
431 |
432 | renv_bootstrap_platform_prefix_impl <- function() {
433 |
434 | # if an explicit prefix has been supplied, use it
435 | prefix <- Sys.getenv("RENV_PATHS_PREFIX", unset = NA)
436 | if (!is.na(prefix))
437 | return(prefix)
438 |
439 | # if the user has requested an automatic prefix, generate it
440 | auto <- Sys.getenv("RENV_PATHS_PREFIX_AUTO", unset = NA)
441 | if (auto %in% c("TRUE", "True", "true", "1"))
442 | return(renv_bootstrap_platform_prefix_auto())
443 |
444 | # empty string on failure
445 | ""
446 |
447 | }
448 |
449 | renv_bootstrap_platform_prefix_auto <- function() {
450 |
451 | prefix <- tryCatch(renv_bootstrap_platform_os(), error = identity)
452 | if (inherits(prefix, "error") || prefix %in% "unknown") {
453 |
454 | msg <- paste(
455 | "failed to infer current operating system",
456 | "please file a bug report at https://github.com/rstudio/renv/issues",
457 | sep = "; "
458 | )
459 |
460 | warning(msg)
461 |
462 | }
463 |
464 | prefix
465 |
466 | }
467 |
468 | renv_bootstrap_platform_os <- function() {
469 |
470 | sysinfo <- Sys.info()
471 | sysname <- sysinfo[["sysname"]]
472 |
473 | # handle Windows + macOS up front
474 | if (sysname == "Windows")
475 | return("windows")
476 | else if (sysname == "Darwin")
477 | return("macos")
478 |
479 | # check for os-release files
480 | for (file in c("/etc/os-release", "/usr/lib/os-release"))
481 | if (file.exists(file))
482 | return(renv_bootstrap_platform_os_via_os_release(file, sysinfo))
483 |
484 | # check for redhat-release files
485 | if (file.exists("/etc/redhat-release"))
486 | return(renv_bootstrap_platform_os_via_redhat_release())
487 |
488 | "unknown"
489 |
490 | }
491 |
492 | renv_bootstrap_platform_os_via_os_release <- function(file, sysinfo) {
493 |
494 | # read /etc/os-release
495 | release <- utils::read.table(
496 | file = file,
497 | sep = "=",
498 | quote = c("\"", "'"),
499 | col.names = c("Key", "Value"),
500 | comment.char = "#",
501 | stringsAsFactors = FALSE
502 | )
503 |
504 | vars <- as.list(release$Value)
505 | names(vars) <- release$Key
506 |
507 | # get os name
508 | os <- tolower(sysinfo[["sysname"]])
509 |
510 | # read id
511 | id <- "unknown"
512 | for (field in c("ID", "ID_LIKE")) {
513 | if (field %in% names(vars) && nzchar(vars[[field]])) {
514 | id <- vars[[field]]
515 | break
516 | }
517 | }
518 |
519 | # read version
520 | version <- "unknown"
521 | for (field in c("UBUNTU_CODENAME", "VERSION_CODENAME", "VERSION_ID", "BUILD_ID")) {
522 | if (field %in% names(vars) && nzchar(vars[[field]])) {
523 | version <- vars[[field]]
524 | break
525 | }
526 | }
527 |
528 | # join together
529 | paste(c(os, id, version), collapse = "-")
530 |
531 | }
532 |
533 | renv_bootstrap_platform_os_via_redhat_release <- function() {
534 |
535 | # read /etc/redhat-release
536 | contents <- readLines("/etc/redhat-release", warn = FALSE)
537 |
538 | # infer id
539 | id <- if (grepl("centos", contents, ignore.case = TRUE))
540 | "centos"
541 | else if (grepl("redhat", contents, ignore.case = TRUE))
542 | "redhat"
543 | else
544 | "unknown"
545 |
546 | # try to find a version component (very hacky)
547 | version <- "unknown"
548 |
549 | parts <- strsplit(contents, "[[:space:]]")[[1L]]
550 | for (part in parts) {
551 |
552 | nv <- tryCatch(numeric_version(part), error = identity)
553 | if (inherits(nv, "error"))
554 | next
555 |
556 | version <- nv[1, 1]
557 | break
558 |
559 | }
560 |
561 | paste(c("linux", id, version), collapse = "-")
562 |
563 | }
564 |
565 | renv_bootstrap_library_root_name <- function(project) {
566 |
567 | # use project name as-is if requested
568 | asis <- Sys.getenv("RENV_PATHS_LIBRARY_ROOT_ASIS", unset = "FALSE")
569 | if (asis)
570 | return(basename(project))
571 |
572 | # otherwise, disambiguate based on project's path
573 | id <- substring(renv_bootstrap_hash_text(project), 1L, 8L)
574 | paste(basename(project), id, sep = "-")
575 |
576 | }
577 |
578 | renv_bootstrap_library_root <- function(project) {
579 |
580 | prefix <- renv_bootstrap_profile_prefix()
581 |
582 | path <- Sys.getenv("RENV_PATHS_LIBRARY", unset = NA)
583 | if (!is.na(path))
584 | return(paste(c(path, prefix), collapse = "/"))
585 |
586 | path <- renv_bootstrap_library_root_impl(project)
587 | if (!is.null(path)) {
588 | name <- renv_bootstrap_library_root_name(project)
589 | return(paste(c(path, prefix, name), collapse = "/"))
590 | }
591 |
592 | renv_bootstrap_paths_renv("library", project = project)
593 |
594 | }
595 |
596 | renv_bootstrap_library_root_impl <- function(project) {
597 |
598 | root <- Sys.getenv("RENV_PATHS_LIBRARY_ROOT", unset = NA)
599 | if (!is.na(root))
600 | return(root)
601 |
602 | type <- renv_bootstrap_project_type(project)
603 | if (identical(type, "package")) {
604 | userdir <- renv_bootstrap_user_dir()
605 | return(file.path(userdir, "library"))
606 | }
607 |
608 | }
609 |
610 | renv_bootstrap_validate_version <- function(version) {
611 |
612 | loadedversion <- utils::packageDescription("renv", fields = "Version")
613 | if (version == loadedversion)
614 | return(TRUE)
615 |
616 | # assume four-component versions are from GitHub; three-component
617 | # versions are from CRAN
618 | components <- strsplit(loadedversion, "[.-]")[[1]]
619 | remote <- if (length(components) == 4L)
620 | paste("rstudio/renv", loadedversion, sep = "@")
621 | else
622 | paste("renv", loadedversion, sep = "@")
623 |
624 | fmt <- paste(
625 | "renv %1$s was loaded from project library, but this project is configured to use renv %2$s.",
626 | "Use `renv::record(\"%3$s\")` to record renv %1$s in the lockfile.",
627 | "Use `renv::restore(packages = \"renv\")` to install renv %2$s into the project library.",
628 | sep = "\n"
629 | )
630 |
631 | msg <- sprintf(fmt, loadedversion, version, remote)
632 | warning(msg, call. = FALSE)
633 |
634 | FALSE
635 |
636 | }
637 |
638 | renv_bootstrap_hash_text <- function(text) {
639 |
640 | hashfile <- tempfile("renv-hash-")
641 | on.exit(unlink(hashfile), add = TRUE)
642 |
643 | writeLines(text, con = hashfile)
644 | tools::md5sum(hashfile)
645 |
646 | }
647 |
648 | renv_bootstrap_load <- function(project, libpath, version) {
649 |
650 | # try to load renv from the project library
651 | if (!requireNamespace("renv", lib.loc = libpath, quietly = TRUE))
652 | return(FALSE)
653 |
654 | # warn if the version of renv loaded does not match
655 | renv_bootstrap_validate_version(version)
656 |
657 | # load the project
658 | renv::load(project)
659 |
660 | TRUE
661 |
662 | }
663 |
664 | renv_bootstrap_profile_load <- function(project) {
665 |
666 | # if RENV_PROFILE is already set, just use that
667 | profile <- Sys.getenv("RENV_PROFILE", unset = NA)
668 | if (!is.na(profile) && nzchar(profile))
669 | return(profile)
670 |
671 | # check for a profile file (nothing to do if it doesn't exist)
672 | path <- renv_bootstrap_paths_renv("profile", profile = FALSE)
673 | if (!file.exists(path))
674 | return(NULL)
675 |
676 | # read the profile, and set it if it exists
677 | contents <- readLines(path, warn = FALSE)
678 | if (length(contents) == 0L)
679 | return(NULL)
680 |
681 | # set RENV_PROFILE
682 | profile <- contents[[1L]]
683 | if (!profile %in% c("", "default"))
684 | Sys.setenv(RENV_PROFILE = profile)
685 |
686 | profile
687 |
688 | }
689 |
690 | renv_bootstrap_profile_prefix <- function() {
691 | profile <- renv_bootstrap_profile_get()
692 | if (!is.null(profile))
693 | return(file.path("profiles", profile, "renv"))
694 | }
695 |
696 | renv_bootstrap_profile_get <- function() {
697 | profile <- Sys.getenv("RENV_PROFILE", unset = "")
698 | renv_bootstrap_profile_normalize(profile)
699 | }
700 |
701 | renv_bootstrap_profile_set <- function(profile) {
702 | profile <- renv_bootstrap_profile_normalize(profile)
703 | if (is.null(profile))
704 | Sys.unsetenv("RENV_PROFILE")
705 | else
706 | Sys.setenv(RENV_PROFILE = profile)
707 | }
708 |
709 | renv_bootstrap_profile_normalize <- function(profile) {
710 |
711 | if (is.null(profile) || profile %in% c("", "default"))
712 | return(NULL)
713 |
714 | profile
715 |
716 | }
717 |
718 | renv_bootstrap_path_absolute <- function(path) {
719 |
720 | substr(path, 1L, 1L) %in% c("~", "/", "\\") || (
721 | substr(path, 1L, 1L) %in% c(letters, LETTERS) &&
722 | substr(path, 2L, 3L) %in% c(":/", ":\\")
723 | )
724 |
725 | }
726 |
727 | renv_bootstrap_paths_renv <- function(..., profile = TRUE, project = NULL) {
728 | renv <- Sys.getenv("RENV_PATHS_RENV", unset = "renv")
729 | root <- if (renv_bootstrap_path_absolute(renv)) NULL else project
730 | prefix <- if (profile) renv_bootstrap_profile_prefix()
731 | components <- c(root, renv, prefix, ...)
732 | paste(components, collapse = "/")
733 | }
734 |
735 | renv_bootstrap_project_type <- function(path) {
736 |
737 | descpath <- file.path(path, "DESCRIPTION")
738 | if (!file.exists(descpath))
739 | return("unknown")
740 |
741 | desc <- tryCatch(
742 | read.dcf(descpath, all = TRUE),
743 | error = identity
744 | )
745 |
746 | if (inherits(desc, "error"))
747 | return("unknown")
748 |
749 | type <- desc$Type
750 | if (!is.null(type))
751 | return(tolower(type))
752 |
753 | package <- desc$Package
754 | if (!is.null(package))
755 | return("package")
756 |
757 | "unknown"
758 |
759 | }
760 |
761 | renv_bootstrap_user_dir <- function() {
762 | dir <- renv_bootstrap_user_dir_impl()
763 | path.expand(chartr("\\", "/", dir))
764 | }
765 |
766 | renv_bootstrap_user_dir_impl <- function() {
767 |
768 | # use local override if set
769 | override <- getOption("renv.userdir.override")
770 | if (!is.null(override))
771 | return(override)
772 |
773 | # use R_user_dir if available
774 | tools <- asNamespace("tools")
775 | if (is.function(tools$R_user_dir))
776 | return(tools$R_user_dir("renv", "cache"))
777 |
778 | # try using our own backfill for older versions of R
779 | envvars <- c("R_USER_CACHE_DIR", "XDG_CACHE_HOME")
780 | for (envvar in envvars) {
781 | root <- Sys.getenv(envvar, unset = NA)
782 | if (!is.na(root))
783 | return(file.path(root, "R/renv"))
784 | }
785 |
786 | # use platform-specific default fallbacks
787 | if (Sys.info()[["sysname"]] == "Windows")
788 | file.path(Sys.getenv("LOCALAPPDATA"), "R/cache/R/renv")
789 | else if (Sys.info()[["sysname"]] == "Darwin")
790 | "~/Library/Caches/org.R-project.R/R/renv"
791 | else
792 | "~/.cache/R/renv"
793 |
794 | }
795 |
796 |
797 | renv_json_read <- function(file = NULL, text = NULL) {
798 |
799 | text <- paste(text %||% read(file), collapse = "\n")
800 |
801 | # find strings in the JSON
802 | pattern <- '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'
803 | locs <- gregexpr(pattern, text)[[1]]
804 |
805 | # if any are found, replace them with placeholders
806 | replaced <- text
807 | strings <- character()
808 | replacements <- character()
809 |
810 | if (!identical(c(locs), -1L)) {
811 |
812 | # get the string values
813 | starts <- locs
814 | ends <- locs + attr(locs, "match.length") - 1L
815 | strings <- substring(text, starts, ends)
816 |
817 | # only keep those requiring escaping
818 | strings <- grep("[[\\]{}:]", strings, perl = TRUE, value = TRUE)
819 |
820 | # compute replacements
821 | replacements <- sprintf('"\032%i\032"', seq_along(strings))
822 |
823 | # replace the strings
824 | mapply(function(string, replacement) {
825 | replaced <<- sub(string, replacement, replaced, fixed = TRUE)
826 | }, strings, replacements)
827 |
828 | }
829 |
830 | # transform the JSON into something the R parser understands
831 | transformed <- replaced
832 | transformed <- gsub("[[{]", "list(", transformed)
833 | transformed <- gsub("[]}]", ")", transformed)
834 | transformed <- gsub(":", "=", transformed, fixed = TRUE)
835 | text <- paste(transformed, collapse = "\n")
836 |
837 | # parse it
838 | json <- parse(text = text, keep.source = FALSE, srcfile = NULL)[[1L]]
839 |
840 | # construct map between source strings, replaced strings
841 | map <- as.character(parse(text = strings))
842 | names(map) <- as.character(parse(text = replacements))
843 |
844 | # convert to list
845 | map <- as.list(map)
846 |
847 | # remap strings in object
848 | remapped <- renv_json_remap(json, map)
849 |
850 | # evaluate
851 | eval(remapped, envir = baseenv())
852 |
853 | }
854 |
855 | renv_json_remap <- function(json, map) {
856 |
857 | # fix names
858 | if (!is.null(names(json))) {
859 | lhs <- match(names(json), names(map), nomatch = 0L)
860 | rhs <- match(names(map), names(json), nomatch = 0L)
861 | names(json)[rhs] <- map[lhs]
862 | }
863 |
864 | # fix values
865 | if (is.character(json))
866 | return(map[[json]] %||% json)
867 |
868 | # handle true, false, null
869 | if (is.name(json)) {
870 | text <- as.character(json)
871 | if (text == "true")
872 | return(TRUE)
873 | else if (text == "false")
874 | return(FALSE)
875 | else if (text == "null")
876 | return(NULL)
877 | }
878 |
879 | # recurse
880 | if (is.recursive(json)) {
881 | for (i in seq_along(json)) {
882 | json[i] <- list(renv_json_remap(json[[i]], map))
883 | }
884 | }
885 |
886 | json
887 |
888 | }
889 |
890 | # load the renv profile, if any
891 | renv_bootstrap_profile_load(project)
892 |
893 | # construct path to library root
894 | root <- renv_bootstrap_library_root(project)
895 |
896 | # construct library prefix for platform
897 | prefix <- renv_bootstrap_platform_prefix()
898 |
899 | # construct full libpath
900 | libpath <- file.path(root, prefix)
901 |
902 | # attempt to load
903 | if (renv_bootstrap_load(project, libpath, version))
904 | return(TRUE)
905 |
906 | # load failed; inform user we're about to bootstrap
907 | prefix <- paste("# Bootstrapping renv", version)
908 | postfix <- paste(rep.int("-", 77L - nchar(prefix)), collapse = "")
909 | header <- paste(prefix, postfix)
910 | message(header)
911 |
912 | # perform bootstrap
913 | bootstrap(version, libpath)
914 |
915 | # exit early if we're just testing bootstrap
916 | if (!is.na(Sys.getenv("RENV_BOOTSTRAP_INSTALL_ONLY", unset = NA)))
917 | return(TRUE)
918 |
919 | # try again to load
920 | if (requireNamespace("renv", lib.loc = libpath, quietly = TRUE)) {
921 | message("* Successfully installed and loaded renv ", version, ".")
922 | return(renv::load())
923 | }
924 |
925 | # failed to download or load renv; warn the user
926 | msg <- c(
927 | "Failed to find an renv installation: the project will not be loaded.",
928 | "Use `renv::activate()` to re-initialize the project."
929 | )
930 |
931 | warning(paste(msg, collapse = "\n"), call. = FALSE)
932 |
933 | })
934 |
--------------------------------------------------------------------------------
/renv/settings.dcf:
--------------------------------------------------------------------------------
1 | external.libraries:
2 | ignored.packages:
3 | package.dependency.fields: Imports, Depends, LinkingTo
4 | r.version:
5 | snapshot.type: implicit
6 | use.cache: TRUE
7 | vcs.ignore.library: TRUE
8 | vcs.ignore.local: TRUE
9 |
--------------------------------------------------------------------------------
/submission.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'How to build a package with "Rmd First" method'
3 | author: "Sébastien Rochette"
4 | date: "28/01/2021"
5 | output: html_document
6 | ---
7 |
8 | ## The title of the tutorial
9 |
10 | How to build a package with "Rmd First" method
11 |
12 | ## Abstract
13 |
14 | "Rmd First" method can reduce mental load when building packages by keeping users in a natural environment, using a tool they know: a RMarkdown document.
15 |
16 | The step between writing your own R code to analyze some data and refactoring it into a well-documented, ready-to-share R package seems unreachable to many R users.
17 | The package structure is sometimes perceived as useful only for building general-purpose tools for data analysis to be shared on official platforms.
18 | However, packages can be used for a broader range of purposes, from internal use to open-source sharing.
19 | Because packages are designed for robustness and enforce helpful standards for documentation and testing, the package structure provides a useful framework for refactoring analyses and preparing them to go into production.
20 | The following approach to write a development or an analysis inside a Rmd, will significantly reduce the work to transform a Rmd into a package :
21 |
22 | - _Design_ : define the goal of your next steps and the tools needed to reach them
23 | - _Prototype_ : use some small examples to prototype your script in Rmd
24 | - _Build_ : Build your script as functions and document your work to be able to use them, in the future, on real-life datasets
25 | - _Strengthen_ : Create tests to assure stability of your code and follow modifications through time
26 | - _Deploy_ : Transform as a well-structured package to deploy and share with your community
27 |
28 | During this tutorial, we will work through the steps of Rmd Driven Development to persuade attendees that their experience writing R code means that they already know how to build a package. They only need to be in a safe environment to find it out, which will be what we propose.
29 | We will take advantage of all existing tools such as {devtools}, {testthat}, {attachment} and {usethis} that ease package development from Rmd to building a package.
30 | The recent package [{fusen}](https://thinkr-open.github.io/fusen), which "inflates a package from a simple flat Rmd", will be presented to further reduce the step between well-designed Rmd and package deployment.
31 | Attendees will leave this workshop having built their first package with the "Rmd First" method and with the skills and tools to build more packages on their own.
32 |
33 | ## The broad topic it covers
34 |
35 | - R Packages: building packages, CRAN submission and package maintenance
36 | - Reproducibility and best practices
37 |
38 | ## The learning goals
39 |
40 | By the end of the tutorial participants should:
41 |
42 | - understand the methodology proposed by Rmd Driven Development
43 | - be able to refactor their code into correctly formatted functions
44 | - understand the structure of a package
45 | - be able to build a documented and tested R package
46 | - know how to share their work with the community on GitHub
47 |
48 | ## Time zone preference and time slot (please mention at least three different time zones you are comfortable with)
49 |
50 | - 1:00pm - 4:00pm UTC
51 | - 2:00pm - 5:00pm UTC
52 | - 3:00pm - 6:00pm UTC
53 |
54 | ## Length of the tutorial
55 |
56 | Tutorial will be 3 hours length.
57 | It will be divided in 3 times 1 hour: ~25’ presentation + 2’ quizz + 28’ exercises + 5’ break
58 |
59 | ## Language in which the tutorial can be taught.
60 |
61 | The tutorial will be taught in English.
62 | However, there will be a possibility for help in French during exercises sessions.
63 |
64 | ## The intended audience and method of online engagement with the audience
65 |
66 | The course will alternate between two formats of instruction:
67 |
68 | - Plenary room : Lecture, presenting slides
69 | - Breakout rooms (if possible): Exercises time. 5 attendees by room (6 rooms). Instructors are not needed in all 6 rooms, but we want to be able to discuss with some, without bothering everyone. Instructors will move from a room to the other and may be summoned over Slack. Teaching assistants may be needed.
70 |
71 | The tutorial is built as a private course.
72 |
73 | - There will only be 30 participants for 3 instructors.
74 | - Attendees are expected to participate and to answer questions.
75 | - Instructors will make sure this participation will be in a safe environment, in plain group and in small groups during exercises.
76 | - Instructors will ask questions to individuals to be sure no one is left behind.
77 | - Attendees should expect to share their screen individually or to the group so that we can help.
78 | - Instructors will try to make the course active and exciting. Attendees are expected to help in this way.
79 |
80 | A chat platform (Slack or equivalent) will be open in parallel to allow chat assistance, attendees interactions and information or resources sharing.
81 |
82 | ## If there exists, a link to the Tutorial materials and/or web page.
83 |
84 | - https://github.com/statnmap/user2021.rmdd
85 |
86 | ## Prerequisites / requirements
87 |
88 | ### Prerequisites
89 |
90 | Upper-beginner to Intermediate.
91 | Attendees should already have experience with R and be able to:
92 |
93 | - Manipulate rectangular data with {dplyr}: select, filter, mutate, group_by, summarize
94 | - Work with RMarkdown documents
95 | - Understand the meaning of this line of code and how to use it:
96 | ```
97 | my_mean <- function(x, na.rm = TRUE) { sum(x, na.rm = na.rm) / length(x) }
98 | ```
99 |
100 | ### Requirements
101 |
102 | - The tutorial will be taught using the [ThinkR e-learning platform, named CRUZ](https://rtask.thinkr.fr/remote-trainings-and-certification/).
103 | Here is a presentation of the platform that will be provided: https://thinkr.fr/Take_a_tour_on_CRUZ.pdf
104 |
105 | - The platform provided by ThinkR is online. No installation is required on attendees computers.
106 | - Attendees will only receive their credentials the day before the tutorial. They will be able to log on the e-learning platform after receiving their credentials.
107 | - All attendees will have their own sessions with all required packages and course material already installed
108 |
109 | - Required equipment
110 | + A computer
111 | + A correct internet connection (You can test your internet connection: we recommend a download value higher than 6 Mb/s)
112 | + A microphone (*compulsory, the default computer mic is perfect*), a webcam if the learner wishes and has one (*possibly the computer’s one if available*), headphones to ensure the learner’s comfort – the ideal being a headset with a microphone
113 | + Good mood 🙂
114 |
115 |
116 | ## Material sharing (license), recording consent
117 |
118 | - Material will be shared on GitHub : https://github.com/statnmap/user2021.rmdd
119 | - Instructors agree to be recorded. Attendees will be notified when recording is on, in particular during plenary room sessions. Recording will be stopped (or deleted) during exercises time
120 |
121 |
122 | ## A brief biography of the instructors
123 |
124 | - Sébastien Rochette (@statnmap) is R trainer and consultant at [ThinkR](https://rtask.thinkr.fr).
125 | He participates in the development of open-source R packages proposed on GitHub by ThinkR and himself, including {fusen} and {attachment}. He also has created multiple internal packages for ThinkR and different clients.
126 | He gave different presentations and tutorials on package development with the 'Rmd first' method as summed up in ["Rmd first: When development starts with documentation"](https://rtask.thinkr.fr/when-development-starts-with-documentation/) and blogs about R [on his website](https://statnmap.com).
127 | He is co-author of the book ["Engineering Production-Grade Shiny Apps"](https://engineering-shiny.org/) that promotes an adapted RMDD method for Shiny application using {golem}.
128 |
129 | - Emily Riederer (@emilyriederer) is a Senior Analytics Manager at Capital One where she leads a team building analytics infrastrucutre in R. Emily is a proponent of [R Markdown Driven Development](https://emilyriederer.netlify.app/post/rmarkdown-driven-development/) and a co-author of the [R Markdown Cookbook](https://bookdown.org/yihui/rmarkdown-cookbook/). She also maintains the {projmgr} and {convo} R packages, and frequently blogs about R [on her website](emily.rbind.io).
130 |
--------------------------------------------------------------------------------
/teach-package-dev-rmdfirst.Rproj:
--------------------------------------------------------------------------------
1 | Version: 1.0
2 |
3 | RestoreWorkspace: Default
4 | SaveWorkspace: Default
5 | AlwaysSaveHistory: Default
6 |
7 | EnableCodeIndexing: Yes
8 | UseSpacesForTab: Yes
9 | NumSpacesForTab: 2
10 | Encoding: UTF-8
11 |
12 | RnwWeave: Sweave
13 | LaTeX: pdfLaTeX
14 |
15 | AutoAppendNewline: Yes
16 | StripTrailingWhitespace: Yes
17 |
18 | BuildType: Package
19 | PackageUseDevtools: Yes
20 | PackageInstallArgs: --no-multiarch --with-keep.source
21 |
--------------------------------------------------------------------------------