class: right middle hide-count background-color: white background-image: url(img/enso.jpg) background-position: left <link href="https://fonts.googleapis.com/css?family=Cedarville+Cursive|Karla|Montserrat|Open+Sans|Quattrocento|Raleway&display=swap" rel="stylesheet"> <style type="text/css"> a, a > code { color: #D55E00FF; text-decoration: none; } em { color: #D55E00FF; font-style: normal; } del { color: #E5E5E5; text-decoration: none; font-weight: normal; } .inverse del { color: #6C7B7F; } .bg-white-o90{ background-color: rgba(255, 255, 255, 0.9); } .large { font-size: 175% } .hide-count .remark-slide-number { display: none; } .text-poster { font-family: 'Cinzel', serif; } .inverse { color: #b9bfca; background-color: #282D35 } .inverse.remark-slide-number { color: #b9bfca; } .remark-code-line-highlighted { color: #D55E00FF; background-color: transparent; } .remark-inline-code { color: #b9bfca; } code { line-height: 120% } .h2 { font-family: 'Karla' } h1, h2, h3 { font-weight: normal; } .dim { color: #6C7B7F; } </style> .pull-right[ # You're already ready: ## Zen and the Art of R Package development ] Malcolm Barrett <svg style="height:0.8em;top:.04em;position:relative;fill:#282D35;" viewBox="0 0 512 512"><path d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"/></svg> @malco_barrett Slides: [bit.ly/rsg-zenrpkgs](http://bit.ly/rsg-zenrpkgs) --- class: center middle
.footnote.pull-right[— Hadley Wickham] --- class: center, middle, hide-count background-image: url(img/oxherding_1.jpg) background-size: cover --- class: center middle
.footnote.pull-right[— Sandokai] --- class: center middle
--- class: center, middle, hide-count background-image: url(img/oxherding_2.jpg) background-size: cover
You already<br>structure your project
--- class: inverse, large ``` ├── data/ ├── reports/ ├── scripts/ └── analysis.Rproj ``` --- class: inverse, large ``` ├── data/ ├── reports/ *├── R/ └── analysis.Rproj ``` --- class: inverse, large ``` *├── data/ ├── reports/ ├── R/ └── analysis.Rproj ``` --- class: inverse, large ``` ├── data/ *├── vignettes/ ├── R/ └── analysis.Rproj ``` --- class: inverse, large ``` ├── data/ ├── vignettes/ ├── R/ *├── man/ *├── tests/ *├── DESCRIPTION *├── NAMESPACE └── analysis.Rproj ``` --- class: inverse, large <code> <em> library(usethis)<br /> create_package("../zenartrpkgs")<br /> </em> </code> --- class: inverse, large <code> <del> library(usethis)<br /> create_package("../zenartrpkgs")<br /><br /> </del> <span style='color:#a8cc8d'>✓</span> Creating <span style='color:#6fbbed'>'zenartrpkgs'</span><br /> <span style='color:#a8cc8d'>✓</span> Creating <span style='color:#6fbbed'>'R/'</span><br /> <span style='color:#a8cc8d'>✓</span> Writing <span style='color:#6fbbed'>'DESCRIPTION'</span><br /> <span style='color:#a8cc8d'>✓</span> Writing <span style='color:#6fbbed'>'NAMESPACE'</span><br /> <span style='color:#a8cc8d'>✓</span> Writing <span style='color:#6fbbed'>'zenartrpkgs.Rproj'</span><br /> <span style='color:#a8cc8d'>✓</span> Adding <span style='color:#6fbbed'>'.Rproj.user'</span> to <span style='color:#6fbbed'>'.gitignore'</span><br /> <span style='color:#a8cc8d'>✓</span> Adding <span style='color:#6fbbed'>'^zenartrpkgs\\\\.Rproj'</span> to <span style='color:#6fbbed'>'.Rbuildignore'</span><br /> <span style='color:#a8cc8d'>✓</span> Setting active project to <span style='color:#6fbbed'>'zenartrpkgs'</span> </code> --- class: inverse, large ``` ├── data/ ├── vignettes/ ├── R/ ├── man/ ├── tests/ *├── DESCRIPTION ├── NAMESPACE └── analysis.Rproj ``` --- class: inverse ``` Package: zenartofrpkgs Title: What the Package Does (One Line, Title Case) Version: 0.0.0.9000 Authors@R: person(given = "Malcolm", family = "Barrett", role = c("aut", "cre"), email = "malcolmbarrett@gmail.com", comment = c(ORCID = "0000-0003-0299-5825")) Description: What the package does (one paragraph). License: MIT + file LICENSE Encoding: UTF-8 LazyData: true ``` --- class: inverse, large <code> <em>create_project("../zenartrpkgs")</em><br /><br /> <span style='color:#a8cc8d'>✓</span> Creating <span style='color:#6fbbed'>'zenartrpkgs'</span><br /> <span style='color:#a8cc8d'>✓</span> Creating <span style='color:#6fbbed'>'R/'</span><br /> <span style='color:#a8cc8d'>✓</span> Writing <span style='color:#6fbbed'>'zenartrpkgs.Rproj'</span><br /> <span style='color:#a8cc8d'>✓</span> Adding <span style='color:#6fbbed'>'.Rproj.user'</span> to <span style='color:#6fbbed'>'.gitignore'</span><br /> <span style='color:#a8cc8d'>✓</span> Setting active project to <span style='color:#6fbbed'>'zenartrpkgs'</span> </code> --- class: inverse, large <code> <del> create_project("../zenartrpkgs")<br /><br /> ✓ Creating 'zenartrpkgs'<br /> ✓ Creating 'R/'<br /> ✓ Writing 'zenartrpkgs.Rproj'<br /> ✓ Adding '.Rproj.user' to '.gitignore'<br /> ✓ Setting active project to 'zenartrpkgs'<br /><br /> </del> <em>use_description()</em><br /><br /> <span style='color:#a8cc8d'>✓</span> Writing <span style='color:#6fbbed'>'DESCRIPTION'</span><br /> </code> --- class: inverse, large <code> <del> create_project("../zenartrpkgs")<br /><br /> ✓ Creating 'zenartrpkgs'<br /> ✓ Creating 'R/'<br /> ✓ Writing 'zenartrpkgs.Rproj'<br /> ✓ Adding '.Rproj.user' to '.gitignore'<br /> ✓ Setting active project to 'zenartrpkgs'<br /><br /> </del> <del> use_description()<br /><br /> ✓ Writing 'DESCRIPTION'<br /><br /> </del> <em>usethis:::is_package()</em><br /> [1] TRUE<br /> </code> --- class: center, middle, hide-count background-image: url(img/oxherding_3.jpg) background-size: cover
You already<br>write R code
--- class: inverse, large <code> iris %>%<br /> group_by(Species) %>%<br /> summarize(mean_sepal_length = mean(Sepal.Length))<br /> <del># A tibble: 3 x 2</del><br /> Species mean_sepal_length<br /> <del><span style="font-style:italic"><fct></span></del> <del><span style="font-style:italic"><dbl></span></del><br /> 1 setosa 5.01<br /> 2 versicolor 5.94<br /> 3 virginica 6.59<br /> </code> --- class: inverse, large <code> use_r("summarize_data")<br /><br /> <span style='color:#e88388'>●</span> Modify <span style='color:#6fbbed'>'summarize_data.R'</span><br /> </code> --- class: inverse, large <code> <del>use_r("summarize_data")<br /><br /> ● Modify 'summarize_data.R'<br /><br /></del> </code> <code> <del># in 'R/summarize_data.R'</del><br /> <em>summarize_iris <- function() {</em><br /> iris %>%<br /> group_by(Species) %>%<br /> summarize(<br /> mean_sepal_length = mean(Sepal.Length)<br /> )<br /> <em>}</em> </code> --- class: inverse, large <code> library(devtools)<br /> <em>load_all()</em> <del># Cmd/Ctrl + Shift + L</del><br /><br /> <span style="font-weight:bold">Loading zenartrpkgs</span> --- class: inverse, large <code> <del> library(devtools)<br /> load_all() # Cmd/Ctrl + Shift + L<br /><br /> <span style="font-weight:bold">Loading zenartrpkgs</span><br /><br /> </del> <em>summarize_iris()</em><br /> <del># A tibble: 3 x 2</del><br /> Species mean_sepal_length<br /> <del><span style="font-style:italic"><fct></span></del> <del><span style="font-style:italic"><dbl></span></del><br /> 1 setosa 5.01<br /> 2 versicolor 5.94<br /> 3 virginica 6.59<br /> </code> --- class: center, middle, hide-count background-image: url(img/oxherding_4.jpg) background-size: cover
You already<br>declare your dependencies
--- class: inverse, large <code> library(dplyr)<br /> library(ggplot2)<br /><br /> plot_iris <- function() {<br /> iris %>%<br /> group_by(Species) %>%<br /> summarize(<br /> mean_sepal_length = mean(Sepal.Length)<br /> ) %>%<br /> ggplot(aes(mean_sepal_length, Species)) +<br /> geom_point()<br /> } </code> --- class: inverse, large <code> <del> library(<em>dplyr</em>)<br /> library(<em>ggplot2</em>)<br /><br /> plot_iris <- function() {<br /> iris %>%<br /> group_by(Species) %>%<br /> summarize(<br /> mean_sepal_length = mean(Sepal.Length)<br /> ) %>%<br /> ggplot(aes(mean_sepal_length, Species)) +<br /> geom_point()<br /> } </del> </code> --- class: inverse, large <code> <del># use_pipe()<br /></del> <em>use_package("dplyr")</em><br /><br /> <span style='color:#a8cc8d'>✓</span> Adding <span style='color:#6fbbed'>'dplyr'</span> to <span style='color:#a8cc8d'>Imports</span> field in DESCRIPTION<br /> <span style='color:#e88388'>●</span> Refer to functions with <span style='color:#6C7B7F'>`dplyr::fun()`</span><br /><br /> </code> --- class: inverse, large <code> <del># use_pipe()<br /> use_package("dplyr")<br /><br /> ✓ Adding 'dplyr' to Imports field in DESCRIPTION<br /> ● Refer to functions with `dplyr::fun()` </del><br /><br /> <em>use_package("ggplot2")</em><br /><br /> <span style='color:#a8cc8d'>✓</span> Adding <span style='color:#6fbbed'>'ggplot2'</span> to <span style='color:#a8cc8d'>Imports</span> field in DESCRIPTION<br /> <span style='color:#e88388'>●</span> Refer to functions with <span style='color:#6C7B7F'>`ggplot2::fun()`</span><br /><br /> </code> --- class: inverse, large <code> <del> plot_iris <- function() {<br /> iris %>%<br /> group_by(Species) %>%<br /> summarize(<br /> mean_sepal_length = mean(Sepal.Length)<br /> ) %>%<br /> ggplot(aes(mean_sepal_length, Species)) +<br /> geom_point()<br /> } </del> </code> --- class: inverse, large <code> <del> plot_iris <- function() {<br /> iris %>%<br /> <em>dplyr::</em>group_by(Species) %>%<br /> <em>dplyr::</em>summarize(<br /> mean_sepal_length = mean(Sepal.Length)<br /> ) %>%<br /> <em>ggplot2::</em>ggplot(<br /> <em>ggplot2::</em>aes(mean_sepal_length, Species)<br /> ) +<br /> <em>ggplot2::</em>geom_point()<br /> } </del> </code> --- class: inverse, dim ``` Package: zenartofrpkgs Title: What the Package Does (One Line, Title Case) Version: 0.0.0.9000 Authors@R: person(given = "Malcolm", family = "Barrett", role = c("aut", "cre"), email = "malcolmbarrett@gmail.com", comment = c(ORCID = "0000-0003-0299-5825")) Description: What the package does (one paragraph). License: MIT + file LICENSE Encoding: UTF-8 LazyData: true ``` --- class: inverse, dim ``` Package: zenartofrpkgs Title: What the Package Does (One Line, Title Case) Version: 0.0.0.9000 Authors@R: person(given = "Malcolm", family = "Barrett", role = c("aut", "cre"), email = "malcolmbarrett@gmail.com", comment = c(ORCID = "0000-0003-0299-5825")) Description: What the package does (one paragraph). License: MIT + file LICENSE Encoding: UTF-8 LazyData: true *Imports: * ggplot2 * dplyr ``` --- class: inverse, large <code> <del># install all dependencies in DESCRIPTION</del><br /> install_deps() </code> --- class: center, middle, hide-count background-image: url(img/oxherding_5.jpg) background-size: cover
You already<br>test your code
--- class: inverse, large <code> clean_data(iris)<br /><br /> <span style="font-weight:bold;color:#A71E00FF">Error: Something went wrong</span><br /><br /> </code> --- class: inverse, large <code> <del> clean_data(iris)<br /><br /> <span style="font-weight:bold">Error: Something went wrong</span><br /><br /> </del> emo::ji("thinking")<br /><br /> 🤔 </code> --- class: inverse, large <code> clean_data(<em>iris[, -5]</em>)<br /><br /> <span style='color:#a8cc8d'>✓</span> Cleaned <span style='color:#6C7B7F'>`iris`</span><br /><br /> emo::ji("thinking")<br /><br /> 🤔 <br /><br /> </code> --- class: inverse, large <code> use_test("clean_data")<br /><br /> <span style='color:#a8cc8d'>✓</span> Adding <span style='color:#6fbbed'>'testthat'</span> to <span style='color:#a8cc8d'>Imports</span> field in DESCRIPTION<br /> <span style='color:#a8cc8d'>✓</span> Creating <span style='color:#6fbbed'>'tests/testthat/'</span><br /> <span style='color:#a8cc8d'>✓</span> Writing <span style='color:#6fbbed'>'tests/testthat.R'</span><br /> <span style='color:#e88388'>●</span> Call <span style='color:#6C7B7F'>`use_test()`</span> to initialize a basic test file and open it for editing.<br /> <span style='color:#a8cc8d'>✓</span> Increasing <span style='color:#6fbbed'>'testthat'</span> version to <span style='color:#6fbbed'>'>= 2.1.0'</span> in DESCRIPTION<br /> <span style='color:#a8cc8d'>✓</span> Writing <span style='color:#6fbbed'>'tests/testthat/test-clean_data.R'</span><br /> </code> --- class: inverse, large <code> <em>test()</em> <del># Cmd/Ctrl + Shift + T</del><br /><br /> <span style="font-weight:bold">Loading zenartrpkgs</span><br /> <span style="font-weight:bold">Testing zenartrpkgs</span><br /><br /><br /> ── <span style="font-weight:bold">Results</span> ──────────────────<br /> OK: <span style='color:#a8cc8d'>1</span><br /> Failed: <span style='color:#a8cc8d'>0</span><br /> Warnings: <span style='color:#a8cc8d'>0</span><br /> Skipped: <span style='color:#a8cc8d'>0</span><br /> </code> --- class: inverse, center, middle, hide-count --- class: inverse # *Use a description file* --- class: inverse # ~~Use a description file~~ # *Write code as functions* --- class: inverse # ~~Use a description file~~ # ~~Write code as functions~~ # *Write down your tests; automate them* --- class: center, middle, hide-count background-image: url(img/oxherding_10.jpg) background-size: cover
Coming home<br>to R packages
--- class: inverse, center, middle ## [My Organizaton's First R Package](https://my-org-first-pkg-2020.netlify.com/) # [R Packages, 2nd Edition: Whole Game](https://r-pkgs.org/whole-game.html) --- class: inverse, center, middle # an invitation -- ## *create a package: a personal R package, something for your work, or turn a project into a package* --- class: center middle
.footnote.pull-right[— Chögyam Trungpa Rinpoche] --- class: inverse ``` *> message [1] "thanks for coming!" *> name [1] "Malcolm Barrett" *> twitter [1] "@malco_barrett" *> github [1] "@malcolmbarrett" *> website [1] "https://malco.io/" *> r_courses [1] "https://malco.io/training" *> slides_made_with [1] "xaringan" *> also [1] "xanringanthemer" "xaringanExtra" *> art_by [1] "Kaz Tanahashi" "Jikihara Gyokusei" ```