R packages: documentation and testing

I was asked to look into how to start documenting R package scripts, and building automating testing of those scripts (aka unit testing). The following provides the slides and some key resources that I used to answer these questions for the team.

Slides

Full screen presentation Use arrows to navigate slides
(you may need to click on the slideshow for it to work).

Essential packages

install.packages("devtools") 
install.packages("usethis")
install.packages("testthat")
install.packages("roxygen2")

Core Functions

  1. Create a new package: bcgovr::create_bcgov_package()
  2. Create a new script: usethis::use_r("function")
  3. Load and ad-hoc test scripts: devtools::load_all() (CTRL + SHIFT + L)
  4. Setup automatic - unit testing
    • Start testing for the project: usethis::use_testthat()
    • Start testing for a function: usethis::use_test("function")
  5. A couple simple tests:
    • testthat::expect_equal()
    • testthat::expect_error()
  6. review how much of your code is being tested: covr::report()

Core documentation tags

#' @title       ## Implied 
#' @description ## Implied 
#' @details     ## Implied 
#' @params      ## What the function needs 
#' @return      ## what the function returns 
#' @export      ## makes the function available 
#' @examples    ## Needs to actually have an examples

Short-cut keys: CTRL + SHIFT + ALT + Rremember you need to have the cursor inside the function you are looking to document.

Key Resources

Key resources used:


Sample Script

Simple function

The following was saved as: ~/R/pem_people.R

#' PEM People
#'
#' PEM People are great!
#'
#' Takes a number and writes a sentance
#'
#' @param x A positive integer
#'
#' @return Returns a character string.
#'
#' @examples
#' pem_people(4)


pem_people <- function(x) {
  ## Error testing
  stopifnot(is.numeric(x),
            x == as.integer(x),
            x >= 0,
            length(x) == 1 )


  if (x == 1) {pem_person(x)} else {
  paste("There are", x, "cool pem people in Smithers")
}}

pem_person <- function(x){
  paste("There is",x, "cool pem person in Smithers")

}

Test script

This test script was saved to: ~/tests/testthat/test-pem_people.R

test_that("Grammar", {
  expect_equal(pem_people(1), "There is 1 cool pem person in Smithers")
  expect_equal(pem_people(5), "There are 5 cool pem people in Smithers")
  })

test_that("Errors", {
  expect_error(pem_people("one"))
  expect_error(pem_people(1:4))
  expect_error(pem_people(-1))
  expect_error(pem_people(pi))
})
Colin Chisholm RPF
Colin Chisholm RPF
Forest Manager

Interested in forests and ecology