Skip to content

Instantly share code, notes, and snippets.

@eliotmonaco
Last active April 26, 2025 16:28
Show Gist options
  • Save eliotmonaco/f1c1b558120ea576c1768a8594ddf275 to your computer and use it in GitHub Desktop.
Save eliotmonaco/f1c1b558120ea576c1768a8594ddf275 to your computer and use it in GitHub Desktop.
My R package dev assistant
# About -------------------------------------------------------------------
# This is a cheatsheet of code snippets and workflows that I've been adding to
# since I started my first package. I keep it open in RStudio while doing any
# dev work so I can execute code directly from the script. It owes a ton to "R
# Packages (2e)" by Hadley Wickham and Jennifer Bryan, still my main package dev
# reference. Please use and modify this as you see fit. FYI, I use RStudio for
# code editing, GitHub for versioning, and pkgdown for the package website, so
# this is written with those tools in mind.
# Pre-setup prep ----------------------------------------------------------
# Useful refs to bookmark
# - R Packages (2e) (https://r-pkgs.org/)
# - Writing R Extensions (https://cran.r-project.org/doc/manuals/r-release/R-exts.html)
# - Happy Git and GitHub for the useR (https://happygitwithr.com/index.html)
# Install these packages
install.packages(
"devtools", "usethis", "roxygen2", "testthat", "knitr",
"desc", "credentials", "gitcreds", "covr"
)
# Create a GitHub account and a personal access token (PAT). Store the PAT in a
# password manager (e.g., LastPass), and save the GH credentials and PAT in
# RStudio using `gitcreds::gitcreds_set()`.
# New package setup -------------------------------------------------------
usethis::create_package(path = "")
# Initialize the README.rmd file
usethis::use_readme_rmd()
# Edit README manually (at least get rid of the placeholder plot)
# Build README.md from README.Rmd
devtools::build_readme()
# Set up testing infrastructure
usethis::use_testthat(3)
# Initial setup to use pkgdown for the package website
usethis::use_pkgdown()
# Initialize local git repo, modify `.gitignore`, and first commit (optional)
usethis::use_git()
# Connect to GitHub
usethis::use_github() # I do this manually
# Create the remote repo and connect the local to the remote
# usethis recommends these GitHub action (GHA) workflows
usethis::use_github_action("check-standard")
usethis::use_github_action("test-coverage")
usethis::use_github_action("pr-commands")
# Necessary to use the test-coverage GHA
usethis::use_coverage("codecov")
# Set up a Codecov.io account here: https://docs.codecov.com/docs/quick-start
# The package's GH repo must be linked to the Codecov.io account. A secret isn't
# necessary if the GH repo is public.
# Use GH Actions to build site, and use GH Pages to host site
usethis::use_pkgdown_github_pages()
# Namespace file ----------------------------------------------------------
# Add a package & function (for any pkg::fn explicitly imported using
# @importFrom)
usethis::use_import_from("", "")
# Description file --------------------------------------------------------
# Add MIT license
usethis::use_mit_license()
# Add author
usethis::use_author(
given = "",
family = "",
role = c("aut", "cre"),
email = "",
comment = c(ORCID = "")
)
# Add dependency
usethis::use_package("", type = "Imports", min_version = NULL)
# Add optional package
usethis::use_package("rmarkdown", type = "Suggests", min_version = NULL)
# Remove a dependency
desc::desc_del_dep("")
# Increment the package version number
usethis::use_version()
# Format Description
usethis::use_tidy_description()
# Website -----------------------------------------------------------------
# Create a new vignette/article
usethis::use_vignette(name = "", title = "")
library(pkgdown)
# Build README.md from README.Rmd
devtools::build_readme()
# Build site (except README.md)
devtools::document()
build_site()
# Build index
devtools::document()
build_reference()
# Build all vignettes/articles
devtools::document()
build_articles()
# Preview local site files in browser
preview_site()
# Data --------------------------------------------------------------------
# Workflow to add or change data:
# - Add data source to `data-raw/`
# - Add script to modify data to `data-raw/`
# - For exported data: save to `data/`
# - For exported data: document data set in `R/data-<dataset_name>.R`
# - For internal data: add to `sysdata.rda` via `data-raw/internal-data.R`
# Add to the bottom of a data script for exported data
usethis::use_data(dataset, overwrite = T)
# Create internal data (`sysdata.rda`)
load("data/dataset1.rda")
source("data-raw/data-script.R")
usethis::use_data(
dataset1,
dataset2,
internal = TRUE,
overwrite = TRUE
)
# Create/add data to `data-raw/`
usethis::use_data_raw()
# If R CMD check gives a warning about compressing data
# - Note the type of compression recommended in the warning and add it to the
# DESCRIPTION file as a new field on a new line, e.g.,
# LazyDataCompression: xz
# - Add the "--resave-data" option when running R CMD check:
devtools::check(build_args = "--resave-data")
# - Modify the R CMD check GitHub action (`.github/workflows/R-CMD-check.yaml`)
# to include "--resave-data" here:
# - uses: r-lib/actions/check-r-package@v2
# with:
# upload-snapshots: true
# build_args: 'c("--no-manual","--compact-vignettes=gs+qpdf","--resave-data")'
# ^^^^^^^^^^^^^^^^
# Testing -----------------------------------------------------------------
# Create/edit tests
fn <- "" # name of the function script file (no file extension)
usethis::use_r(fn) # create/open function script
usethis::use_test(fn) # create/open test script
devtools::load_all()
testthat::test_file(paste0("tests/testthat/test-", fn, ".R")) # run test file
# Run all tests
devtools::load_all()
devtools::test()
# Check/build -------------------------------------------------------------
devtools::load_all()
devtools::document()
devtools::check()
# Build package: `CTRL+SHIFT+B`
# Misc --------------------------------------------------------------------
# Add files to .Rbuildignore
usethis::use_build_ignore(c(""))
# Add an R Markdown template
usethis::use_rmarkdown_template("")
# List all packages currently attached in the global environment
devtools::loaded_packages()
# On invisible returns: "In general, any function called primarily for a side
# effect (like <-, print(), or plot()) should return an invisible value
# (typically the value of the first argument)."
# From Advanced R 2e, section 6.7.2 (Invisible values)
# roxygen2 lists:
#' \describe{
#' \item{item}{description}
#' }
#' \describe{
#' \item{item}{description
#' \itemize{
#' \item bulleted item
#' }
#' }
#' }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment