R package checklist

Rpkg
RSE

A checklist to make CRAN-worthy R packages

Author

Chi Zhang

Published

May 19, 2023

This checklist is being updated over time. Mostly for my own use; but great if it helps you as well!

For a complete treatment, please refer to R Packages (2e) by Hadley Wickham and Jennifer Bryan.

Start building your package

The usethis package will help with the procedure when you do not have a package yet.

You can also create a template, and copy paste from it in the future.

Key components

usethis::create_package('path_to_pkg/pkgname') 

It opens a new R project (directory) named pkgname, with the following items:

  • DESCRIPTION
  • NAMESPACE
  • directory R/
  • .Rbuildignore and .gitignore
  • and the project icon, pkgname.Rproj.

If you have an existing R project but wish to build a package there, copy everything but pkgname.Rproj, and modify the files in your existing pkg directory.

usethis::use_mit_license() # modify name to yours
usethis::use_readme_md() # if you do not have this already
usethis::use_news_md()
usethis::use_test()

# create a folder for future data documentation
x <- 1 
usethis::use_data() 

In addition, URL and bug reports should be added in the DESCRIPTION.

Write functions

Create exported functions in R/, development code in script (or somewhere else).

Documentation

You need to configure the Build tools.

These three things should be done:

Function documentation

Create a function f1, and put your cursor on it. Go to Code -> Insert Roxygen Skeleton to create the template.

Alternatively, use #' to start.

#' A simple placehold function 
#'
#' @param x a numeric value
#'
#' @return a value 3 greater than the input
#' @export
#'
#' @examples 
#' f1(5)
f1 <- function(x){
  x+3
}

Data documentation

It can be beneficial to create a separate file to document data only, say data_documentation.R under the R/ directory.

#' Placeholder data x
#'
#' This dataset contains one value, x
#'
#' @format
#' \describe{
#' \item{x}{The placeholder data x}
#' }
#' @examples
#' print(x)
"x"

Vignette documentation

usethis::use_vignette('your_vignette')

Deploy to pkgdown

Check this reference here

Build package and check

It is possible that your checks don’t pass on the first try.

Don’t forget to check these!

These aspects are quite important to check as well: documentation, code quality, exceptions among others.

Documentation

Sufficient, working examples

  • README.md
  • Help pages
  • Vignettes

Example code coverage, covr::package_coverage(), use GHA workflow to check if code coverage is above a threshold.

Detect broken README examples by generating README.md on every commit.

In help pages, some examples have tags:

  • \dontrun{}: not run by example(), not run by R CMD check
  • \donttest{}: run by example() but not checked
  • \dontshow{}: run and checked
# code coverage
covr::package_coverage(type = c('examples', 'vignettes'), commentDonttest = F, commentDontrun = F)

# readme examples
rmarkdown::render("README.rmd", output_format = rmarkdown::github_document())

# help page examples
devtools::run_examples(run_dontrun = T, run_donttest = T)

# check vignette examples
pkgdown::build_site()

Handling exceptions

Error > warning > message

Code quality

Style guide, styler::style_pkg() enforces tidyverse style guide.

Lint (code smells). Can be removed with styler

# code quality assessment
lint(text = 'x = 1') # with lint
lint(text = 'x <- 1') # no lint
lintr::lint_package()

A workflow that work(ed) for me

CRAN Submission

Final checks

When you are almost ready to submit your package to CRAN, you need to do a few checks.

A good practice is to check while you build your package, so that you’ve already fixed most of the problems by the time you do the final check.

These are a few final checks to do.

# spell check
devtools::spell_check()

# windows check
devtools::check_win_devel()

# rhub cran check 
rhub::check_for_cran()

Remember to check your email and fix potential problems! Some problems pop up in different places, so make sure you fix as many as possible.

Submit

There are a few ways to submit. I found this one to be the most convenient way:

devtools::release()

It asks a few questions to remind you whether all the checks havve passed, and whether you’ve updated the relevant information in DESCRIPTION, NEWS. In the end, it creates a tar ball and submits automatically to CRAN.

You need to check your email to confirm submission, just like when you do it manually via the webform.

Alternatively, you can either

  • write R CMD build PKGNAME in the terminal;
  • in Rstudio, in Build tab select build binary.

Afterwards, submit manually via the webform.