Step-by-Step Guide to Creating R packages

How to create an R package with Rstudio and devtools.




In R, the fundamental unit of shareable code is the package. A package bundles together code, data, documentation, and tests, and is easy to share with others. As of June 2019, there were over 14,000 packages available on the Comprehensive R Archive Network, or CRAN, the public clearing house for R packages. In this article I describe how to create a R package step-by-step so that others can easily download and use your code.

"In R, the fundamental unit of shareable code is the package. A package bundles together code, data, documentation, and tests, and is easy to share with others." Hadley Wickham

Prerequisites

Softwares

R packages

Host your package on github

To register your package on CRAN or bioconductor can be long and requires your project to be mature enough. You can still share your project with project by hosting it on github.

  1. Sign up/in to github and create a new repository.
  2. Check the github repository address on the github quick set up page.
  3. On Rstudio open a new project as new folder R package. Activate the use git option. For instance, I call the package mon_premier_package. This will create a ready-to-use empty R package.
  4. Connect your local R package to the github repository. Go to terminal in Rstudio and type:
git init
git add .
git commit -m "init R package"
git remote add origin < github repository address >
git push origin master
  1. That's it ! Your R package is hosted as an online github repository.

This automatically creates the bare bone files and directories needed to define our R package called mon_premier_package.

mon_premier_package
├── R
├── man
├── mon_premier_package.Rproj
├── DESCRIPTION
├── NAMESPACE

Build the package

In Rstudio, click on Check then Install and restart. These commands will automatically install your package. Alternatively, you can run these commands from the terminal:

devtools::check()
devtools::install()

Then your package is ready-to-use and available. It can be installed in any R session with devtools using install_github function:

if (!requireNamespace("devtools", quietly = TRUE)) { install.packages("devtools") }
library(devtools)
devtools::install_github("Pierre/mon_premier_package")
library(mon_premier_package)

Now you can share the skeleton of your package to anybody, so let's add muscle and skin to it.

Add Functions

Write R file in R Folder

Our package wouldn’t do much without functions. Let’s add a function. Here the R file hello_world.R contains the code source for the function hellow_world:

#' @title Say Hello
#'
#' @description Creates a string with hello word
#'
#' @param name A string
#' @return a string
#' @export
#' @example

hello_world <- function(name) {
    res <- "hello "+name
    return(res)
}
mon_premier_package
├── R
│   ├── hello_world.R
├── mon_premier_package.Rproj
├── DESCRIPTION
├── NAMESPACE

Write documentation

To create documentation describing your function.

devtools::document()
roxygen2::roxygenize()

This will generate a man folder and .Rd documentation files describing functions in R folder.

mon_premier_package
├── R
│   ├── hello_world.R
├── man
│   ├── hello_world.Rd 
├── mon_premier_package.Rproj
├── DESCRIPTION
├── NAMESPACE

Check the documentation is working well:

help(hello_world)

This command returns:

Say Hello
Description
Creates a string with hello word

Usage
hello_world(name)
Arguments
name
A string

Value
a string

Continuous integration with travis

Build Status

The idea behind continuous integration is that CI will automatically run R CMD check (along with your tests, etc.) every time you push a commit to GitHub. CI automatically checks the code after every commit and return you if the build is a succes or not. See blog post by Julia Silge for a beginner's guide to Travis-CI for R.

Conclusion

Here we learnt how to quickly build a R package. Creating R package is a critical skill for any scientist, and something I encourage others to do regularly. Package help isolate our work inside useful abstractions, improves reproducibility, makes our work shareable, and is the first step towards designing better software.

References