How to Create an R Package

Irene Steves, Mitchell Maier

Why write a package?

  • organize code and data
  • reuse code more easily
  • test code
  • share code with others

“Seriously, it doesn’t have to be about sharing your code (although that is an added benefit!). It is about saving yourself time.” –Hilary Parker

Package structure

  • R code (/R)
  • Documentation (/man)
  • Tests (/tests)
  • Package metadata (DESCRIPTION)
  • Namespace (NAMESPACE)
  • Data (/data)
  • Vignettes (/vignettes)
  • Compiled code (/src)
  • Installed files (/inst)
  • Other components


Create a package in RStudio

Option 1

File –> New Project –> New Directory –> R Package

Option 2


Package naming requirements: (1) only letters, numbers, and periods; (2) must start with a letter; (3) cannot end with a period

Write a function

say_aloha <- function(name, print = TRUE) {

  message <- paste("Aloha,",

  if (print) {


As always, remember to write descriptive function names that don't overlap with existing functions


Add checks to your function

These should be included inside your function:


if (!(is.character(name))) {
  stop("Name must be a non empty character. Input a name you want to say aloha to!")

Checking inputs to the function is easy to do and saves lots of debugging headaches later on by (a) stopping the function early and (b) giving you an understandable error message.

Write your documentation

Use Tools –> Roxygen Quick Reference as a template

Common sections:

  • title
  • @description
  • @param - parameters/arguments
  • @examples - examples of how to use your function
  • @export - make this function available to package users (helper functions do not need this)
  • @import/@importFrom - import packages/functions from other packages; used to generate the NAMESPACE

Use import calls instead of library or require calls

Document your function:

#' Say Aloha
#' @description This function will say aloha to any inputted name.
#' @param name (character) A name to say aloha to.
#' @param print (logical) Option to print your message. Defaults to \code{TRUE}
#' @return (character) An aloha message
#' @examples
#' # Say hello to a friend
#' friend <- "Irene"
#' say_aloha(friend)
#' @importFrom crayon bgGreen
#' @importFrom emo ji
#' @export

Document your package:

Auto-generates your help files (/man) and NAMESPACE file:

# delete any *.Rd or NAMESPACE files before running for the first time

Check your package

checking package dependencies ... ERROR
Namespace dependencies not required: ‘crayon’ ‘emo’

See section ‘The DESCRIPTION file’ in the ‘Writing R Extensions’

Description File

Package: greetings
Title: What the Package Does (one line, title case)
Authors@R: person("First", "Last", email = "", role = c("aut", "cre"))
Description: What the package does (one paragraph).
Depends: R (>= 3.3.0)
License: What license is it under?
Encoding: UTF-8
LazyData: true
RoxygenNote: 6.0.1

Edit Description File

Package: greetings
Title: Say Aloha to a Friend
Version: 0.1
Authors@R: c(
  person("Irene", "Steves", comment = "", role = c("aut")),
  person("Mitchell", "Maier", email = "", role = c("cre", "aut")))
Description: This package provides a pleasant way to say hello or goodbye to a friend.
Depends: R (>= 3.3.0)
License: CC0
Encoding: UTF-8
LazyData: true
RoxygenNote: 6.0.1
Imports: crayon, emo
Remotes: hadley/emo
Suggests: testthat

Check your package again


Unit tests

Rather than checking your functions ad-hoc, write unit tests to formalize these checks and make sure your function works the way you think it should!

  • fewer bugs
  • better code structure
  • easier restarts
  • robust code

Write a unit test

New R script: test_FUNCTION_NAME.R

context("say_aloha function")

test_that("function takes one input", {
  testthat::expect_error(say_aloha(c("Irene", "Mitchell")))

Connect to GitHub

  1. Create an empty GitHub repo with the same name

  2. In the Terminal (Tools –> Shell), set up your user name and email if you haven't already:

    git config --global YOUR_NAME
    git config --global GITHUB_EMAIL
  3. Link to GitHub and push your local files to your online GitHub repository

    git remote add origin
    # make a commit
    git push -u origin master


Make sure your package passes all the checks and get it on GitHub!

Install your neighbor's package and take a look at their documentation.

# ?reponame::function_name

Advanced topics

Travis - continuous integration