Package Development
Use pkg::fun() inside package code (or @importFrom pkg fun); never call library() in a package.
44.1 Create a package
install.packages(c("devtools", "usethis", "roxygen2", "testthat"))
usethis::create_package("~/mypkg")
usethis::use_git(); usethis::use_github()
usethis::use_mit_license("Your Name")
usethis::use_r("greet") # creates R/greet.R
usethis::use_test("greet") # creates tests/testthat/test-greet.R
usethis::use_package("dplyr") # add to Imports in DESCRIPTION
usethis::use_readme_rmd(); usethis::use_news_md(); usethis::use_vignette("intro")
usethis::use_pkgdown(); usethis::use_github_action("check-standard")
usethis::use_data(my_dataset) # bundle data44.2 Package structure
mypkg/
├── DESCRIPTION # metadata, dependencies (Imports, Suggests), version
├── NAMESPACE # exports/imports (generated by roxygen2)
├── R/ # R code
├── man/ # documentation (generated)
├── tests/testthat/ # unit tests
├── vignettes/ # long-form docs
├── data/ # exported datasets
├── inst/ # extra files (inst/extdata)
├── src/ # C/C++/Rust code
└── README.Rmd, NEWS.md, LICENSE44.3 Documentation with roxygen2
Use pkg::fun() inside package code (or @importFrom pkg fun); never call library() in a package.
#' Greet someone
#'
#' @param name A character string with the person's name.
#' @param punct Punctuation to append. Defaults to "!".
#' @return A greeting string.
#' @examples
#' greet("Ann")
#' @export
greet <- function(name, punct = "!") {
stopifnot(is.character(name))
paste0("Hello, ", name, punct)
}devtools::document() # generate man/ and NAMESPACE44.4 Testing with testthat
test_that("greet works", {
expect_equal(greet("Ann"), "Hello, Ann!")
expect_type(greet("x"), "character")
expect_error(greet(1))
expect_snapshot(greet("Bob", "?"))
expect_true(nchar(greet("A")) > 0)
expect_warning(as.numeric("x"))
expect_length(letters, 26)
})devtools::test(); covr::package_coverage()44.5 The development loop
devtools::load_all() # Ctrl+Shift+L — load the package without installing
devtools::document() # Ctrl+Shift+D
devtools::test() # Ctrl+Shift+T
devtools::check() # Ctrl+Shift+E — R CMD check (must pass with 0 errors/warnings/notes for CRAN)
devtools::install()
devtools::build()
pkgdown::build_site() # documentation website44.6 Publishing
CRAN: follow the CRAN policies, devtools::check(remote = TRUE, manual = TRUE), rhub::rhub_check(), devtools::check_win_devel(), usethis::use_release_issue(), devtools::submit_cran().
R-universe — build & host packages from GitHub.
Bioconductor — its own review process.
GitHub — pak::pak("user/repo").
Read *R Packages* (Wickham & Bryan, free online) for the full process.