Agent-almanac write-roxygen-docs
install
source · Clone the upstream repo
git clone https://github.com/pjt222/agent-almanac
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/pjt222/agent-almanac "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/write-roxygen-docs" ~/.claude/skills/pjt222-agent-almanac-write-roxygen-docs-d222da && rm -rf "$T"
manifest:
skills/write-roxygen-docs/SKILL.mdsource content
Write Roxygen Documentation
Create complete roxygen2 documentation for R package functions, datasets, and classes.
When to Use
- Adding documentation to a new exported function
- Documenting internal helper functions
- Documenting package datasets
- Documenting S3/S4/R6 classes and methods
- Fixing documentation-related
notesR CMD check
Inputs
- Required: R function, dataset, or class to document
- Optional: Related functions for cross-referencing (
,@family
)@seealso - Optional: Whether the function should be exported
Procedure
Step 1: Write Function Documentation
Place roxygen comments directly above the function:
#' Compute the weighted mean of a numeric vector #' #' Calculates the arithmetic mean of `x` weighted by `w`. Missing values #' in either `x` or `w` are handled according to the `na.rm` parameter. #' #' @param x A numeric vector of values. #' @param w A numeric vector of weights, same length as `x`. #' @param na.rm Logical. Should missing values be removed? Default `FALSE`. #' #' @return A single numeric value representing the weighted mean. #' #' @examples #' weighted_mean(1:5, rep(1, 5)) #' weighted_mean(c(1, 2, NA, 4), c(1, 1, 1, 1), na.rm = TRUE) #' #' @export #' @family summary functions #' @seealso [stats::weighted.mean()] for the base R equivalent weighted_mean <- function(x, w, na.rm = FALSE) { # implementation }
Expected: Complete roxygen block with title, description,
@param for each parameter, @return, @examples, and @export.
On failure: If unsure about a tag, check
?roxygen2::rd_roclet. Common omission is @return, which is required by CRAN for all exported functions.
Step 2: Essential Tags Reference
| Tag | Purpose | Required for export? |
|---|---|---|
| First line, one sentence | Yes |
| Paragraph after blank line | Yes |
| Parameter documentation | Yes |
| Return value description | Yes (CRAN) |
| Usage examples | Strongly recommended |
| Add to NAMESPACE | Yes, for public API |
| Group related functions | Recommended |
| Cross-references | Optional |
| Mark as internal | For non-exported docs |
Expected: All required tags for the function type are identified. Exported functions have
@param, @return, @examples, and @export at minimum.
On failure: If a tag is unfamiliar, consult the roxygen2 documentation for usage and syntax.
Step 3: Document Datasets
Create
R/data.R:
#' Example dataset of city temperatures #' #' A dataset containing daily temperature readings for major cities. #' #' @format A data frame with 365 rows and 4 variables: #' \describe{ #' \item{date}{Date of observation} #' \item{city}{City name} #' \item{temp_c}{Temperature in Celsius} #' \item{humidity}{Relative humidity percentage} #' } #' @source \url{https://example.com/data} "city_temperatures"
Expected:
R/data.R contains roxygen blocks for each dataset with @format describing the structure and @source providing data provenance.
On failure: If
R CMD check warns about undocumented datasets, ensure the quoted string (e.g., "city_temperatures") exactly matches the object name saved with usethis::use_data().
Step 4: Document the Package
Create
R/packagename-package.R:
#' @keywords internal "_PACKAGE" ## usethis namespace: start ## usethis namespace: end NULL
Expected:
R/packagename-package.R exists with @keywords internal and the "_PACKAGE" sentinel. Running devtools::document() generates man/packagename-package.Rd.
On failure: If
R CMD check reports a missing package documentation page, verify the file is named R/<packagename>-package.R and contains the "_PACKAGE" string.
Step 5: Handle Special Cases
Functions with dots in names (S3 methods):
#' @export #' @rdname process process.myclass <- function(x, ...) { # S3 method }
Reusing documentation with
@inheritParams:
#' @inheritParams weighted_mean #' @param trim Fraction of observations to trim. trimmed_mean <- function(x, w, na.rm = FALSE, trim = 0.1) { # implementation }
No visible binding fix using
.data pronoun:
#' @importFrom rlang .data my_function <- function(df) { dplyr::filter(df, .data$column > 5) }
Expected: Special cases (S3 methods, inherited params,
.data pronoun) are documented correctly. @rdname groups S3 methods together. @inheritParams reuses parameter docs without duplication.
On failure: If
R CMD check warns about "no visible binding for global variable," add #' @importFrom rlang .data or use utils::globalVariables() as a last resort.
Step 6: Generate Documentation
devtools::document()
Expected:
man/ directory updated with .Rd files for each documented object. NAMESPACE regenerated with correct exports and imports.
On failure: Check for roxygen syntax errors. Common issues: unclosed brackets in
\describe{}, missing #' prefix on a line, or invalid tag names. Run devtools::document() again after fixing.
Validation
- Every exported function has
,@param
, and@return@examples -
runs without errorsdevtools::document() -
shows no documentation warningsdevtools::check() -
tags group related functions correctly@family - Examples run without errors (test with
)devtools::run_examples()
Common Pitfalls
- Missing
: CRAN requires all exported functions to document their return value@return - Examples that need internet/auth: Wrap in
with a comment explaining why\dontrun{} - Slow examples: Use
for examples that work but take too long for CRAN\donttest{} - Markdown in roxygen: Enable with
in DESCRIPTIONRoxygen: list(markdown = TRUE) - Forgetting to run
: Man pages are generated, not hand-writtendevtools::document()
Related Skills
- initial package setup including roxygen configurationcreate-r-package
- test the functions you documentwrite-testthat-tests
- long-form documentation beyond function referencewrite-vignette
- documentation requirements for CRANsubmit-to-cran