class: center, middle, inverse, title-slide .title[ # Package Development 101 ] .date[ ### November 22, 2023 ] --- ### Why create a package? - Packages are a natural extension of functions - When you have many interrelated functions it can be useful to combine them into one location (ie. a package) - It's easier to share your code and collaborate with others - They provide documentation, examples, and are tested to be robust <img src="data:image/png;base64,#../documents/package.PNG" width="50%" style="display: block; margin: auto;" /> --- # Package Overview .img-right[ <img src="data:image/png;base64,#../documents/r_pic.png" width="461" /> ] .unwrap[ <black>Libraries</black> <gray>Creating a Package</gray> <br> <br> <gray>Structure</gray> <br> <br> <gray>Elements</gray> <br> <br> <gray>Development</gray> <br> <br> <gray>Final Checks</gray> <br> <br> <gray>Maintaining</gray> <br> <br> <gray>Resources</gray> ] --- ### Package Overview: Libraries **'RTools'** - 'RTools' is required to develop packages in R - Make sure you install the correct RTools for your R version (**[RTools versions](https://cran.r-project.org/bin/windows/Rtools/)**) ```r install.packages('rtools') library('rtools') ``` <div class="gray2">'devtools'</div> --- ### Package Overview: Libraries <div class="gray2">'Rtools'</div> **'devtools'** - 'devtools' contains many useful and necessary functions to properly and easily setup the framework for a package - 'devtools' includes other necessary packages such as: 'usethis', 'testthat', and 'roxygen2' ```r install.packages('devtools') library('devtools') ``` --- # Package Overview .img-right[ <img src="data:image/png;base64,#../documents/r_pic.png" width="461" /> ] .unwrap[ <gray>Libraries</gray> <br> <br> <black>Creating a Package</black> <br> <br> <gray>Structure</gray> <br> <br> <gray>Elements</gray> <br> <br> <gray>Development</gray> <br> <br> <gray>Final Checks</gray> <br> <br> <gray>Maintaining</gray> <br> <br> <gray>Resources</gray> ] --- ### Package Overview: Creating a Package 1) Create a new project <img src="data:image/png;base64,#../documents/new_project.PNG" width="645" /> <gray2>2) Start a new directory</gray2> <br> <br> <gray2>3) Select 'R Package'</gray2> <br> <br> <gray2>4) Name your package and setup a git repository to track changes</gray2> --- ### Package Overview: Creating a Package <gray2>1) Create a new project</gray2> 2) Start a new directory <img src="data:image/png;base64,#../documents/new_directory.png" width="646" /> <gray2>3) Select 'R Package'</gray2> <br> <br> <gray2>4) Name your package and setup a git repository to track changes</gray2> --- ### Package Overview: Creating a Package <gray2>1) Create a new project</gray2> <br> <br> <gray2>2) Start a new directory</gray2> 3) Select 'R Package' <img src="data:image/png;base64,#../documents/create_package.png" width="644" /> <gray2>4) Name your package and setup a git repository to track changes</gray2> --- ### Package Overview: Creating a Package <gray2>1) Create a new project</gray2> <br> <br> <gray2>2) Start a new directory</gray2> <br> <br> <gray2>3) Select 'R Package'</gray2> 4) Name your package and setup a git repository to track changes <img src="data:image/png;base64,#../documents/package_name.png" width="639" /> --- # Package Overview .img-right[ <img src="data:image/png;base64,#../documents/r_pic.png" width="461" /> ] .unwrap[ <gray>Libraries</gray> <br> <br> <gray>Creating a Package</gray> <br> <br> <black>Structure</black> <br> <br> <gray>Elements</gray> <br> <br> <gray>Development</gray> <br> <br> <gray>Final Checks</gray> <br> <br> <gray>Maintaining</gray> <br> <br> <gray>Resources</gray> ] --- ### Package Overview: Structure .img-right[ <img src="data:image/png;base64,#../documents/folders.PNG" width="348" /> ] .unwrap[ - Key folders: - R - man - vignettes - tests - Key files: - NAMESPACE - README - DESCRIPTION - LICENSE ] --- # Package Overview .img-right[ <img src="data:image/png;base64,#../documents/r_pic.png" width="461" /> ] .unwrap[ <gray>Libraries</gray> <br> <br> <gray>Creating a Package</gray> <br> <br> <gray>Structure</gray> <br> <br> <black>Elements</black> <br> <br> <gray>Development</gray> <br> <br> <gray>Final Checks</gray> <br> <br> <gray>Maintaining</gray> <br> <br> <gray>Resources</gray> ] --- ### Package Overview: Elements <black2>1) 'DESCRIPTION' file</black2> - Describes important elements in a package - Package name and author - Version - Description of the package - License information - Package imports/suggestions <gray2>2) 'README' file</gray2> <br> <br> <gray2>3) 'NAMESPACE' file</gray2> <br> <br> <gray2>4) 'LICENSE' file</gray2> <br> <br> <gray2>5) 'R' folder</gray2> <br> <br> <gray2>6) 'man' folder</gray2> <br> <br> <gray2>7) 'vignettes' folder</gray2> <br> <br> <gray2>8) 'tests' folder</gray2> <br> <br> <gray2>9) 'data' folder</gray2> --- ### Package Overview: Elements <gray2>1) 'DESCRIPTION' file</gray2> <br> <br> <black2>2) 'README' file .sub_bullet[ - Provides GitHub users an overview of the package - Description, purpose, and examples - There are two types of README files - README.Rmd, which allows R chunks (it is an Rmd after all!) - README.md, which is just a basic README unless rendered from an Rmd README - It is recommended to build your README as an Rmd, which will be rendered as an md file that appears nicely in GitHub ] </black2> <gray2>3) 'NAMESPACE' file</gray2> <br> <br> <gray2>4) 'LICENSE' file</gray2> <br> <br> <gray2>5) 'R' folder</gray2> <br> <br> <gray2>6) 'man' folder</gray2> <br> <br> <gray2>7) 'vignettes' folder</gray2> <br> <br> <gray2>8) 'tests' folder</gray2> <br> <br> <gray2>9) 'data' folder</gray2> --- ### Package Overview: Elements <gray2>1) 'DESCRIPTION' file</gray2> <br> <br> <gray2>2) 'README' file</gray2> <br> <br> <black2>3) 'NAMESPACE' file</black2> .sub_bullet[ - Updated/created automatically using roxygen2 - Ensures the package is self contained - Exports and imports required packages ] <gray2>4) 'LICENSE' file</gray2> <br> <br> <gray2>5) 'R' folder</gray2> <br> <br> <gray2>6) 'man' folder</gray2> <br> <br> <gray2>7) 'vignettes' folder</gray2> <br> <br> <gray2>8) 'tests' folder</gray2> <br> <br> <gray2>9) 'data' folder</gray2> --- ### Package Overview: Elements <gray2>1) 'DESCRIPTION' file</gray2> <br> <br> <gray2>2) 'README' file</gray2> <br> <br> <gray2>3) 'NAMESPACE' file</gray2> <br> <br> <black2>4) 'LICENSE' file</black2> .sub_bullet[ - The license associated with the package - This holds the copyright information for the package ] <gray2>5) 'R' folder</gray2> <br> <br> <gray2>6) 'man' folder</gray2> <br> <br> <gray2>7) 'vignettes' folder</gray2> <br> <br> <gray2>8) 'tests' folder</gray2> <br> <br> <gray2>9) 'data' folder</gray2> --- ### Package Overview: Elements <gray2>1) 'DESCRIPTION' file</gray2> <br> <br> <gray2>2) 'README' file</gray2> <br> <br> <gray2>3) 'NAMESPACE' file</gray2> <br> <br> <gray2>4) 'LICENSE' file</gray2> <br> <br> <black2>5) 'R' folder</black2> .sub_bullet[ - Where all of the code lives for the package - Automatically created when a package is created ] <gray2>6) 'man' folder</gray2> <br> <br> <gray2>7) 'vignettes' folder</gray2> <br> <br> <gray2>8) 'tests' folder</gray2> <br> <br> <gray2>9) 'data' folder</gray2> --- ### Package Overview: Elements <gray2>1) 'DESCRIPTION' file</gray2> <br> <br> <gray2>2) 'README' file</gray2> <br> <br> <gray2>3) 'NAMESPACE' file</gray2> <br> <br> <gray2>4) 'LICENSE' file</gray2> <br> <br> <gray2>5) 'R' folder</gray2> <br> <br> <black2>6) The 'man' folder</black2> .sub_bullet[ - Documentation that will fill the help page for your packages functions and objects - Created automatically using Roxygen2 based on the params included in each script ] <gray2>7) 'vignettes' folder</gray2> <br> <br> <gray2>8) 'tests' folder</gray2> <br> <br> <gray2>9) 'data' folder</gray2> --- ### Package Overview: Elements <gray2>1) 'DESCRIPTION' file</gray2> <br> <br> <gray2>2) 'README' file</gray2> <br> <br> <gray2>3) 'NAMESPACE' file</gray2> <br> <br> <gray2>4) 'LICENSE' file</gray2> <br> <br> <gray2>5) 'R' folder</gray2> <br> <br> <gray2>6) The 'man' folder</gray2> <br> <br> <black2>7) The 'vignettes' folder<black2> .sub_bullet[ - Provide detailed tutorials - Provide examples/reasons for common errors or warnings in the package - Can provide information on new features - Multiple vignettes can be provided per package ] <gray2>8) 'tests' folder</gray2> <br> <br> <gray2>9) 'data' folder</gray2> --- ### Package Overview: Elements <gray2>1) 'DESCRIPTION' file</gray2> <br> <br> <gray2>2) 'README' file</gray2> <br> <br> <gray2>3) 'NAMESPACE' file</gray2> <br> <br> <gray2>4) 'LICENSE' file</gray2> <br> <br> <gray2>5) 'R' folder</gray2> <br> <br> <gray2>6) The 'man' folder</gray2> <br> <br> <gray2>7) The 'vignettes' folder</gray2> <br> <br> <black2>8) 'tests' folder</black2> .sub_bullet[ - Setup tests to ensure your package is working as intended - Test if the proper errors, warnings, or messages appear when certain conditions are met ] <gray2>9) 'data' folder</gray2> --- ### Package Overview: Elements <gray2>1) 'DESCRIPTION' file</gray2> <gray2>2) 'README' file</gray2> <gray2>3) 'NAMESPACE' file</gray2> <gray2>4) 'LICENSE' file</gray2> <gray2>5) 'R' folder</gray2> <gray2>6) The 'man' folder</gray2> <gray2>7) The 'vignettes' folder</gray2> <gray2>8) 'tests' folder</gray2> <black2>9) 'data' folder</black2> - A place to include datasets that you want to be accessible through your package --- # Package Overview .img-right[ <img src="data:image/png;base64,#../documents/r_pic.png" width="461" /> ] .unwrap[ <gray>Libraries</gray> <br> <br> <gray>Creating a Package</gray> <br> <br> <gray>Structure</gray> <br> <br> <gray>Elements</gray> <br> <br> <black>Development</black> <br> <br> <gray>Final Checks</gray> <br> <br> <gray>Maintaining</gray> <br> <br> <gray>Resources</gray> ] --- ### Package Overview: Development #### The 'DESCRIPTION' file .img-right[ <img src="data:image/png;base64,#../documents/description.PNG" width="436" /> ] .unwrap[ - This file is automatically generated - You will need to mostly fill it out manually - Sections can be filled in automatically - For example setting the packages used in the package ```r usethis::use_package('dplyr') ``` ] --- ### Package Overview: Development #### The 'README' file .img-right[ <img src="data:image/png;base64,#../documents/readme.PNG" width="495" /> ] .unwrap[ - Create a README.Rmd and manually fill it out ```r usethis::use_readme_rmd() ``` - Update the README.md file by knitting this file or running ```r devtools::build_readme() ``` ] --- ### Package Overview: Development #### The 'NAMESPACE' file - This is an automatically updated file - Update it by doing ```r devtools::document() ``` <img src="data:image/png;base64,#../documents/namespace.PNG" width="358" /> --- ### Package Overview: Development #### The 'LICENSE' file - Copyright your work by calling one of these *Note: there are other licenses you can call beyond these* ```r usethis::use_mit_license() usethis::use_gpl3_license() usethis::use_proprietary_license() ``` <img src="data:image/png;base64,#../documents/license.PNG" width="381" /> --- ### Package Overview: Development #### R Scripts - Create your R scripts as you normally would - These will be singular functions - Set up your @params at the top of the script to fill out your function manual <img src="data:image/png;base64,#../documents/params.PNG" width="425" /> --- ### Package Overview: Development #### Manuals - Found in the 'man' folder - These are generated automatically based on the @params found at the top of your R scripts - These form your help tab for your functions in the UI for your functions and objects - Update your manuals by doing ```r devtools::document() ``` --- ### Package Overview: Development #### Vignettes .img-right[ <img src="data:image/png;base64,#../documents/vignette.PNG" width="478" /> ] .unwrap[ - Create a vignette by calling ```r usethis::use_vignette('vignette_name') ``` - Fill it out manually now that it has been created ] --- ### Package Overview: Development #### Tests .img-right[ <img src="data:image/png;base64,#../documents/test.PNG" width="417" /> ] .unwrap[ - First you need to setup a test infrastructure ```r usethis::use_testthat() ``` - Next create a test file ```r usethis::use_test('test_name') ``` - Create your tests using the package 'testthat' - Test for warnings, errors, and warnings ```r testthat::test_that(testing_code) ``` - Run the tests using ```r testthat::test() ``` ] --- ### Package Overview: Development #### Data - To make datasets accessible through your package simply save your data by doing *Note: this also makes a 'data' folder for your package* ```r usethis::use_data(df) ``` - This function will save the data as an '.rda' file - Data files should have an accompanying R script with set parameters and details of the dataframe - Code for this script should simply just be 'NULL' below the parameters --- # Package Overview .img-right[ <img src="data:image/png;base64,#../documents/r_pic.png" width="461" /> ] .unwrap[ <gray>Libraries</gray> <br> <br> <gray>Creating a Package</gray> <br> <br> <gray>Structure</gray> <br> <br> <gray>Elements</gray> <br> <br> <gray>Development</gray> <br> <br> <black>Final Checks</black> <br> <br> <gray>Maintaining</gray> <br> <br> <gray>Resources</gray> ] --- ### Package Overview: Final Checks <black2>Test your package</black2> .sub_bullet[ - Use this code to run your preset tests ] ```r testthat::test() ``` <gray2>Check your package</gray2> <br> <br> <gray2>Build your package</gray2> --- ### Package Overview: Final Checks <div class="gray2">Test your package</div> Check your package - Run checks on the package - This will return any potential problems, missing elements, or errors within the package ```r devtools::check() ``` <div class="gray2">Build your package</div> --- ### Package Overview: Final Checks <gray2>Test your package</gray2> <gray2>Check your package</gray2> <black2>Build your package</black2> .sub_bullet[ - Once your tests and checks are complete you can finally build your package ] ```r devtools::build() ``` --- # Package Overview .img-right[ <img src="data:image/png;base64,#../documents/r_pic.png" width="461" /> ] .unwrap[ <gray>Libraries</gray> <br> <br> <gray>Creating a Package</gray> <br> <br> <gray>Structure</gray> <br> <br> <gray>Elements</gray> <br> <br> <gray>Development</gray> <br> <br> <gray>Final Checks</gray> <br> <br> <black>Maintaining</black> <br> <br> <gray>Resources</gray> ] --- ### Package Overview: Maintaining <div class="black2">Install your package locally</div> - This is an important step, you will want to make sure it installs and runs normally now that it has been transformed into a zip file ```r install.packages("path/package_name.tar.gz") ``` <gray2>Uploading your package to GitHub</gray2> <br> <br> <gray2>Installing from GitHub</gray2> <br> <br> <gray2>Bug Fixing and Updating</gray2> --- ### Package Overview: Maintaining <div class="gray2">Install your package locally</div> Uploading your package to GitHub - You will need a GitHub account then follow these steps: 1) **[Create a git repo](https://kbroman.org/github_tutorial/pages/init.html)** and DO NOT create a README file 2) Commit all of your changes locally 3) Connect and push to the repository in the terminal by doing ```r git remote add origin https://github.com/username/reponame git branch -M main git push -u origin main ``` - Benefits - Allows you to track changes in your code - Others can easily review, provide input and collaborate with your package and code - People can easily install your package directly from GitHub <gray2>Installing from GitHub</gray2> <br> <br> <gray2>Bug Fixing and Updating</gray2> --- ### Package Overview: Maintaining <div class="gray2">Install your package locally</div> <br> <div class="gray2">Uploading your package to GitHub</div> Installing from GitHub - The code to install your package from GitHub is as follows ```r devtools::install_github("username/package_repo") ``` <gray2>Bug Fixing and Updating</gray2> --- ### Package Overview: Maintaining <div class="gray2">Install your package locally</div> <br> <div class="gray2">Uploading your package to GitHub</div> <br> <div class="gray2">Installing from GitHub</div> Bug Fixing and Updating - Re-load your package project - Load your 'devtools' package - Now run this to load all of the functions in your package ```r devtools::load_all() ``` - Updating/fixing your package - Apply your updates/fixes - Update the package version found in the 'DESCRIPTION' file - Run your tests, checks, and build your package again - Commit your changes and push to git *Remember all of the same git features exist here, if you are doing testing feel free to leverage branches in git and merge together later with main once you are finished.* --- # Package Overview .img-right[ <img src="data:image/png;base64,#../documents/r_pic.png" width="461" /> ] .unwrap[ <gray>Libraries</gray> <gray>Creating a Package</gray> <gray>Structure</gray> <gray>Elements</gray> <gray>Development</gray> <gray>Final Checks</gray> <gray>Maintaining</gray> <black>Resources</black> ] --- ### Package Overview: Resources **[How to Guide](https://r-pkgs.org/)** **[Another How to Guide](https://bookdown.org/rdpeng/RProgDA/building-r-packages.html)** **[Package Development Cheat Sheet](https://rstudio.github.io/cheatsheets/html/package-development.html)** **[Publishing Packages to GitHub](https://kbroman.org/pkg_primer/pages/github.html)**