19 Packages
Notes from working through: https://r-pkgs.org/
Remember: Git commit after each change
19.1 Packages: set up
Start in a fresh R session in the directory where you want to create the folder (e.g. Documents).
Environment:
* library(devtools)
(if not already installed, will need to run install.packages(“devtools”)
* create_package("~/Documents/packagename")
, which will create a directory (if doesn’t already exist) and populate with .gitignore, .Rbuildignore, DESCRIPTION, NAMESPACE, R folder, and packagename.Rproj. RStudio will open a new window with Rproj activated/open. As it’s a fresh R session, then call library(devtools)
again.
* renv::init()
to set up with renv
* install.packages(c("devtools", "roxygen2", "testthat", "knitr"))
then renv::snapshot()
* library(devtools)
, or add to .Rprofile to always library() it:
if (interactive()) {
suppressMessages(require(devtools))
}
GitHub:
* Make it a GitHub repository - usethis::use_git()
* Rename branch git branch -m master main
* Link with GitHub - usethis::use_github()
. May get error about personal access token if not set. To see if it is set, run gh_token_help()
. To store, use gitcreds::gitcreds_set()
Description, license and readme:
* Edit DESCRIPTION (title, author, description)
* use_mit_license()
to create the license files
* use_readme_rmd()
to create basic README file, add some lines to .Rbuildignore, and creates a Git pre-commit hook to help you keep README.Rmd and README.md in sync. To update README runbuild_readme()
to create README.md from README/Rmd. The advantage of having a README.Rmd file is that you can include code chunks, embed plots, etc. You can also use GitHub Actions to re-render README.Rmd every time you push, example here: https://github.com/r-lib/actions/tree/v1/examples. I have not tried that yet though.
19.2 Packages: adding functions and testing
use_r("functionname")
to create or open script functionname.R in R/ directory. Add the function there (only that, not libraries etc.).
Docstring:
* Open function R file, click cursor within function, then do Code > Insert Roxygen skelecton. * Edit the Rxoygen description. It will include @export. This tells Roxygen2 to add this function to the NAMESPACE file, so that it will be accessible to users. For your first R package, you’ll probably want to include @export for each of your functions.
* Run document()
to update documentation. It will convert the roxygen comment into man/functionname.Rd and write in NAMESPACE
* The @example directive is used when you want to use an external file that contains the examples. If you’re including the example(s) directly in your roxygen documentation then use @examples
. If you don’t want the examples to run (e.g. if providing with a fake file that doesn’t exist, and hence would fail check() as it tests examples work), then use @examplesIf interactive()
* Can now preview helpfile by running ?functionname
* Usage is derived from function specification. Can set manually with @usage
and remove entirely with @usage NULL
Testing:
* use_testthat()
. This initializes the unit testing machinery for your package. It adds Suggests: testthat to DESCRIPTION, creates the directory tests/testthat/, and adds the script tests/testthat.R.
* use_test("functionname")
to create matching testfile.
* library(testthat)
, load_all()
, test()
to run the test. Tests will also run whenever check()
package
* rename_files("strsplit1", "str_split_one")
to rename the R file and will also rename testthat file (which we also edit with new function name), to fit with convention of filename matching function name
19.3 Packages: using other libraries
Based on: https://kbroman.org/pkg_primer/pages/depends.html
* Add libraries that are essential for package to run and that want R to install when install your package to Imports: section of DESCRIPTION FILE. Instead of manual change, can also run use_package(“readxl”) which adds it to Imports section of DESCRIPTION.
* Add required imports to each function - ideally with specific functions - or just whole package - example:
#' @import tidyverse
#' @importFrom readxl read_excel
- Run
check()
to see if issue is resolved
19.4 Packages: loading and checking
load_all()
to simulate process of building, installing and attaching the package. You can then use functions from that package.
check()
to check package is in working order. Read output - it’s easier to deal with these problems earlier
install()
thenlibrary(packagename)
to install and use package in current environment
19.5 Packages - Vignettes:
usethis::use_vignette("my-vignette")
- creates directory, modifies DESCRIPTION, drafts vignette Rmd, adds patterns to .gitignore
install()
,library(package_name)
then knit
If you rename vignette, change VignetteIndexEntry to match title (doesn’t need to match filename). When run, will create new html under docs/articles called newfilename.html. Delete old filename. Build site. Push.
19.6 Packages - Create GitHub pages website:
Initial set-up:
* First step is to ensure set up with git creds. When I first tried this, I had lots of issues with it not working, and realised this was because I hadn’t set it up with the Personal Access Token (PAT). Do this using gitcreds::gitcreds_set()
. Check settings using usethis::gh_token_help()
.
* Next step is to go to repository Settings > Actions > General > Workflow permissions and check “read and write permissions”
Creating site:
* OPTION 1. usethis::use_pkgdown()
, then pkgdown::build_site()
, then remove docs from .gitignore so you can commit them to GitHub, then push to main
* OPTION 2: usethis::use_pkgdown_github_pages()
To update website, rebuild locally using pkgdown::build_site()
then push to GitHub and push to main branch. GitHub pages will always based on files in docs/ folder for source code of website in specified branch (default: main).