#' @export
<- function(x){
square ^2
x }
Lecture 9: R Packages
October 28, 2025
From this topic, students are anticipated to be able to build a basic R package, especially using the devtools
package.
Write a DESCRIPTION file
Carefully curate package dependencies
Document functions and data using roxygen2 comments and tags
Include tests with testthat in accordance with the R package infrastructure.
Add a license
Update an R package via semantic version-ing, NEWS, changelog.
Develop and build informative vignettes and a package README.
Why R Packages?
As mentioned in the “functions” topic, your analysis will probably benefit from homemade functions: making functions forces you to think about your analysis in terms of its key computational parts, and makes for robust and readable code. Here are a few benefits that result by bundling these functions into an R package:
Organized documentation
Sharability
Built-in checks to ensure your package is working
Templates for organizing your work
Easy way to share datasets
The alternative is keeping the functions stored in separate files, and source()
ing them into your analysis scripts, but this can become unwieldy. Plus, if your package becomes really nice, you might want to share it with the world!
For this topic, we’ll be making an R package like the toy square package, by following along with “The Whole Game” Chapter of “R packages”. Here’s a checklist based on that chapter. If you miss class, check out How to Make an R Package video lecture, then try following along using the book, and coming to office hours or asking questions on Slack if you get stuck.
Many of the functions we call are from the devtools
package in R. If you’re getting errors when trying to run some commands, try reloading devtools
in the Console by running library(devtools
).
Minimal Working Example
First, make a minimal viable product:
In any R console, install (if necessary) and load the
devtools
package in the console (do this every time you go to work on your package).- You will create a new R Project in the next step, so don’t worry about the location now.
Run
create_package()
in the console (NOTE: alldevtools
functions should be written in the console).- Better defaults than going through the File menu.
- Set the file path to be wherever you’d like the package to live. I’ll be saving it on my desktop in a (not yet created) folder called “powers” by calling
create_package("~/Desktop/powers")
- Allow access if a pop-up appears, and RStudio will refresh to your new Project.
- If you look at the new folder that was created (mine is on my desktop), you’ll see an R Project, a DESCRIPTION file, a NAMESPACE file, and an R folder where all of your functions will be.
Create a simple function in a .R file, and save it in the R folder
you can do this by navigating to the R folder on the right hand pane of your R Project under “Files”, opening the R folder, and selecting “New File” > “R Script”
Name the file “square.R”. We will be adding a simple function to file with an
#' @export
command to ensure it works properly with our package
In the console, reload
devtools
and run thedocument()
function.- Any function with the
#' @export
tag will be exported to the namespace file which contains a list of functions we want to make available in the R package.
- Any function with the
Run
use_git()
to start using version control and hosting your package on Github:- Prefer to start your project on GitHub? Or locally? Either way, useful instructions for what to do can be found in “Happy Git with R” Part III.
Run
load_all()
in the console to test your package outIf R Restarted, then you need to reload
devtools
before runningload_all()
.see if
square(5)
returns the correct answer
Check that the package is intact: run
check()
in the ConsoleEdit the DESCRIPTION file
First, run
use_mit_license("Your Name")
in the Console.Open the DESCRIPTION file and edit the Author information and Package Title.
: powers Package: Easy computation of powers Title: 0.0.0.9000 Version@R: Authorsperson("YOUR FIRST NAME", "YOUR LAST NAME", , "YOUR EMAIL", role = c("aut", "cre")) : Calculates various powers of numeric data (squares, cubics, etc) Description: MIT + file LICENSE License: UTF-8 Encoding: list(markdown = TRUE) Roxygen: 7.3.2 RoxygenNote: Suggeststestthat (>= 3.0.0) /testthat/edition: 3 Config
Add a README file
Run
use_readme_rmd()
in the Console.Open the RMD file and add some information for the package.
--- : github_document output--- <!-- README.md is generated from README.Rmd. Please edit that file --> # powers Package for STAT545! This is a minimal working example of my first R Package ## Installation Package installation can be done directly by calling`devtools::install_github("YOUR_GITHUB_USERNAME/powers")` ## Example : This is a basic example which shows you how to solve a common problem ::: {.cell} ```{.r .cell-code} library(powers) #> #> Attaching package: 'powers' #> The following object is masked _by_ '.GlobalEnv': #> #> square square(c(2,4,5)) #> [1] 4 16 25 ``` :::
- Render the README every time with
build_readme()
.
Document the function:
Navigate back to the function
square
we made and click anywhere inside of the function. Select “Code” > “Insert roxygen skeleton”Edit the documentation for
param
,returns
, andexamples
. You can also add a@title
and@description
. Here’s what mine looks like:#' @title Square a single value or vector #' @description #' Squares a single numeric value or a numeric vector #' #' @param x, numeric #' #' @returns numeric, vector #' #' @examples #' square(5) #' square(c(4, 5, 6)) #' @export <- function(x){ square ^2 x }
Run
document()
again in the Console.Run
check()
again to make sure your examples are working.
Install and Restart (
Ctrl + Shift + B
(Windows & Linux) orCmd + Shift + B
(macOS)) , or runinstall()
in the console. Try loading the package and using it!
Expand Your Package
Now, let’s expand the R package that we just created:
Run
use_testthat()
in the Console (re-loaddevtools
if R recently restarted)This will create a folder called
tests
and atestthat.R
file which we will add our tests to.Run
use_test("square")
in the Console. This will create a file called test-square.RUpdate it to include the following tests (and save the file!):
test_that("square works", { expect_equal(square(3), 9) expect_equal(square(0), 0) expect_equal(square(c(2,4)), c(4,16)) expect_equal(square(c(3, NA)), c(9, NA)) })
Check all tests with
test()
in the Console. This also happens withcheck()
.
We don’t really need to use functions from another package here, but practice declaring your general intention to use some functions from the dplyr namespace by running
use_package("dplyr")
in the Console only once. Now your package will be able to use thedplyr
package functions.Connect your local package to Github with
use_github()
. Say yes to committing and publishing the changes. Now your package should be on GitHub!Make a vignett, a long-form document that serves as a detailed guide or tutorial for an R package:
use_vignette("powers")
build_vignettes()
.
Include data with the R package with
use_data(R_OBJECT_HERE)
. Then document a string of its name in a new R script using a different collection of roxygen tags.- I’ll add the
mtcars
dataset usinguse_data(mtcars)
- I’ll add the
Release your package:
Make a NEWS.md file with
use_news_md()
and add the main development notes.Commit changes (in Terminal on RStudio)
git add .
git commit -m "Adding Vignette:"
Push Changes (in Terminal on RStudio)
git push origin main
(If you get an error, try going to the Git section in the top right hand pane and push from there)
Tag a release on GitHub.
Recall How to tag a release from the Collaborative Project Milestone 1:
Navigate to the main page (root) of your GitHub repository.
There should be a small link on the right-hand-side of your page that says “Create a new release”. Click that.
For the tag version/name, put
1.0.0
Choose a release title and description (this is less important).
Do not check off “This is a pre-release”.
Click “Publish Release”.
Resources
Video Lecture:
Written material:
See “The Whole Game” Chapter of “R packages” for a concise overview of the entire process of making an R package.
- The entire “R packages” book is overall a great resource to read if you’re wanting to learn more.
See Writing R Extensions, the authoritative and comprehensive (but dry) resource for writing R packages.
To learn more about using S3 object oriented functions in your package, see “Advanced R” Chapter 13: S3.