| name | r-development |
| description | Expert guidance for R package development following best practices for devtools, testthat, roxygen2, and R ecosystem tools |
R Package Development
Use this skill when working with R packages to ensure proper development workflows, testing patterns, and documentation standards.
Development Workflow
Package Building and Management
# Load package for interactive development
devtools::load_all()
# Update documentation (REQUIRED before committing R changes)
devtools::document()
# Run all tests
devtools::test()
# Run specific test file
testthat::test_file("tests/testthat/test-filename.R")
# Run tests matching a pattern
devtools::test(filter = "pattern")
testthat::test_local(filter = "pattern")
# Check package (R CMD check)
devtools::check()
# Build package
devtools::build()
# Install package locally
devtools::install()
# Check with vignettes built
devtools::check(build_args = c("--compact-vignettes=both"))
Code Quality and Style
# Lint package (configuration in .lintr)
lintr::lint_package()
# Lint specific file
lintr::lint("R/filename.R")
# Style code (pre-commit hook typically uses tidyverse style)
styler::style_pkg()
# Check test coverage
covr::package_coverage()
Documentation Building
# Build vignettes
devtools::build_vignettes()
# Build specific vignette
rmarkdown::render("vignettes/name.Rmd")
# Build pkgdown site locally
pkgdown::build_site()
Testing Best Practices
testthat Patterns
Preferred expectations:
expect_identical()>expect_equal()(when exact match expected)- Multiple
expect_true()calls > stacking conditions with&& expect_s3_class()>expect_true(inherits(...))- Use specific
expect_*functions:expect_lt(),expect_gt(),expect_lte(),expect_gte()expect_length()expect_named()expect_type()
Examples:
# Good
expect_identical(result, expected)
expect_s3_class(obj, "data.frame")
expect_lt(value, 10)
expect_true(condition1)
expect_true(condition2)
# Avoid
expect_equal(result, expected) # when identical match is needed
expect_true(inherits(obj, "data.frame"))
expect_true(value < 10)
expect_true(condition1 && condition2)
Test Organisation
- Use testthat edition 3
- Test files named
test-{component}.R - Helper files in
tests/testthat/helper-{name}.R - Setup files in
tests/testthat/setup.Rfor shared fixtures - Custom expectations in
tests/testthat/helper-expectations.R
Conditional Testing
# Skip tests on CRAN
testthat::skip_on_cran()
# Skip if not on CI
testthat::skip_if_not(on_ci())
# Skip if package not available
testthat::skip_if_not_installed("package")
Documentation Standards
roxygen2 Best Practices
Avoid duplication with @inheritParams:
#' @param x Input data
#' @param ... Additional arguments
my_function <- function(x, ...) {}
#' @inheritParams my_function
#' @param y Another parameter
wrapper_function <- function(x, y, ...) {}
Documentation structure:
- One sentence per line in descriptions
- Max 80 characters per line
- Use
@familytags for related functions - Use
@examplesor@examplesIffor examples - UK English spelling
Example documentation:
#' Process input data
#'
#' This function processes the input data according to specified parameters.
#' It returns a processed data frame with additional columns.
#'
#' @param data A data.frame containing the input data
#' @param method Character string specifying the processing method
#'
#' @return A data.frame with processed results
#'
#' @family preprocessing
#'
#' @examples
#' \dontrun{
#' result <- process_data(my_data, method = "standard")
#' }
#'
#' @export
process_data <- function(data, method = "standard") {
# implementation
}
Code Style Guidelines
Naming Conventions
- Internal functions: Prefix with
..internal_helper <- function() {} - Exported functions: Use snake_case
public_function <- function() {}
Formatting
- Max 80 characters per line
- No trailing whitespace
- No spurious blank lines
- Use tidyverse style guide
- Set up pre-commit hooks for automatic formatting
Pre-commit Hooks
Typical .pre-commit-config.yaml includes:
style-files: Auto-format R codelintr: Lint R codereadme-rmd-rendered: Ensure README.md is up-to-dateparsable-R: Check R syntaxdeps-in-desc: Check dependencies are in DESCRIPTION
# Install pre-commit
pip install pre-commit
# Install hooks
pre-commit install
# Run manually
pre-commit run --all-files
Common Data Structures
data.table Usage
Many R packages use data.table for performance:
- Functions often expect/return
data.tableobjects - Use
data.table::setDT()or customcoerce_dt()to ensure input is data.table - Set keys for efficient joins:
data.table::setkey(dt, col) - Use
:=for in-place modification
S3 Classes
- Check class with
inherits()orexpect_s3_class() - Document S3 methods properly
- Export constructors, not internal class definitions
Package Dependencies
Managing Dependencies
# Use specific package functions with ::
package::function()
# Add to DESCRIPTION Imports or Suggests
usethis::use_package("package_name")
usethis::use_package("package_name", type = "Suggests")
Common R Package Ecosystem Tools
- devtools: Development workflow
- testthat: Testing framework
- roxygen2: Documentation generation
- usethis: Package setup automation
- lintr: Code linting
- styler: Code formatting
- covr: Test coverage
- pkgdown: Website generation
When to Use This Skill
Activate this skill when:
- Developing R packages
- Writing R tests
- Documenting R functions
- Setting up R package infrastructure
- Running R package checks
- Working with devtools, testthat, or roxygen2
This skill provides R-specific development patterns. Project-specific architecture and domain knowledge should remain in project CLAUDE.md files.