Developing Your Own R Package

A casual demonstration of modern practices for R package development.

Author
Affiliation

Emi Tanaka

Australian National University

Published

May 23, 2024

This note is available at https://rpubs.com/emitanaka/anu-rpkg-dev.

About

Do you have some code or functions in R that you would like to make and distribute as an R package? Emi will demonstrate some modern practices for R package development and, where time permits, the process of publishing your package on CRAN. The demonstration will be casual and those coming are free to ask questions or share their own tips or tribulations in developing or publishing an R package.

Recognizing software as a first-class research output is a national agenda and there is a clear wave of change coming that will change the research landscape.

Software awards

There are a number of awards available for research software development that you can consider applying for.

National

Global

What are some of your favorite packages?

library(tidyverse)
library(plotly)

What is an R-package?

A container:

  • for a set of R functions,
  • to share data,
  • to share an app,
  • and more, e.g. Rmd templates,

Motivation

What’s the goal?
  • What does your package (and functions) do?
  • Who is it for?
  • Why use it?
  • Where do we find and install it?
  • How do we use it?

đź’ˇ Idea

  • Let’s make a simple set of arithmetic functions.

  • The user interface would look like:

add(1, 3) # 1 + 3
subtract(5, 3) # 5 - 3
divide(6, 3) # 6 / 3
multiply(3, 2) # 3 * 2

Functions

add <- function(x, y) x + y
subtract <- function(x, y) x - y
divide <- function(x, y) x / y
multiply <- function(x, y) x * y

R-package development helper packages

  • devtools
  • usethis
  • roxygen2
  • pkgdown
  • testthat
install.packages(c("devtools", "usethis", "roxygen2", "pkgdown", "testthat"))

Anatomy of an R-package

  • DESCRIPTION file
  • R/ directory for R files that contain your functions
  • NAMESPACE file (you don’t need to manually create this)

Optionally,

  • data/ for binary data available to the user
  • data-raw/ for raw data
  • inst/ for arbitrary additional files that you want include in your package
  • and so on.

DESCRIPTION file

  • Metadata for the package
    • Package name
    • Title and description
    • Authors
    • Dependencies (depends, imports, suggests)
    • Licensing
    • Version number
    • Bug report location, and so on.

Creating an R-package

available::available("maths") # check if package is available
usethis::create_package("maths")
usethis::use_r("new-r-file") # creating new R file in the R/ directory

# add R functions to the R file

devtools::load_all()

Documenting R functions with roxygen2

  • use #' above a function to write documentation for that function

  • roxygen2 uses @ tags to structure documentation, e.g. 

    • any text after @description is the description
    • any text after @param describes the arguments of the function
    • @export signals that it is an exported function
    • any text after @return describes the return object
  • The full list of Rd tags are found at https://roxygen2.r-lib.org/articles/rd.html

  • Then devtools::document() converts the Rd tags to appropriate sections of .Rd files written in the man/ folder

devtools::document()

Unit testing with testthat

usethis::use_test()
  • This creates a file test-active-filename.R in tests/testthat/ directory
test_that("operations works", {
  expect_equal(add(3, 4), 3 + 4)
  expect_equal(subtract(3, 4), 3 - 4)
  expect_equal(divide(3, 4), 3 / 4)
  expect_equal(multiply(3, 4), 3 * 4)
})
devtools::test_active_file()
devtools::test()

Master the keyboard shortcuts

  • Cmd/Ctrl + Shift + L: Load all
  • Cmd/Ctrl + Shift + D: Document
  • Cmd/Ctrl + Shift + T: Test
  • Cmd/Ctrl + Shift + B: Build and Reload
  • plus more… see RStudio IDE > Tools > Keyboard Shortcuts Help

Share and collaborate on your package

usethis::use_git()
usethis::use_github()
  • Install GitHub hosted packages like:
devtools::install_github("user/repo")

Add README

usethis::use_readme_rmd()

Building a website for your package with pkgdown

usethis::use_pkgdown()
# OR, automatic build and deploy with
usethis::use_pkgdown_github_pages()

Whole R package development workflow

available::available("pkgname") # check if package name is available (if planning to publish publicly)
usethis::create_package("pkgname")
usethis::use_git() # set up version control
usethis::use_github() # optional
usethis::use_r("myfile")
# write some functions in a script
usethis::use_data_raw() # if adding data
devtools::load_all() # try it out in the console
usethis::use_package("import-pkgname") # add package to import (or depends or suggests)
usethis::use_package_doc() # add package documentation
usethis::use_pipe() # if you want to add %>% from `magrittr`
usethis::use_vignette("vignette-name") # add vignette
usethis::use_test() # make test file for active R file
# write some test
devtools::test_active_file() # test active file
devtools::test() # test whole package
devtools::build() # build vignettes
devtools::install() # to install package
devtools::check() # to build and check a package 
usethis::use_readme_rmd() # to add a README Rmd file
styler::style_pkg() # optional (commit first, then review changes carefully)
usethis::use_pkgdown_github_pages() # for setting up pkgdown website on github
# `usethis::use_pkgdown()` if not using github pages

Useful reference

Publishing software

Some outlets include:

Domain-specific software also get published in the domain journals, e.g. Bioinformatics, Methods in Ecology and Evolution, and so on.