Skip to content

Documentation and Style

Use one convention from the first function. Code that is easy to read is easier to test, review, and publish.

For R packages in these guides, use the Google R Style Guide, write API documentation with roxygen2, and put unit tests in testthat.

Use BigCamelCase for public functions, snake_case for local objects, and an initial dot for private functions. Use <- for assignment, never right hand assignment. Return the value explicitly. Qualify functions from non base packages with package::function().

#' Calculates counts per million.
#'
#' @param counts A numeric vector of nonnegative read counts.
#' @return A numeric vector scaled to one million reads.
#' @examples
#' CountsPerMillion(c(25, 75))
#' @export
CountsPerMillion <- function(counts) {
stopifnot(
"counts must be numeric" = is.numeric(counts),
"counts must not contain NA" = !anyNA(counts),
"counts must not be negative" = all(counts >= 0),
"counts must have a positive total" = sum(counts) > 0
)
return(counts / sum(counts) * 1e6)
}

The #' lines belong directly above the function they describe. They are not ordinary comments. They are roxygen2 tags that generate the help page and the exported name.

Generate package documentation with roxygen2

Section titled “Generate package documentation with roxygen2”

Start a package once. Add testthat and roxygen2 as development dependencies, then let the package tools create the expected directory structure.

usethis::create_package("geneTools")
usethis::use_testthat(edition = 3)
usethis::use_roxygen_md()

Place source files in R/. Run this after adding or changing a roxygen block:

devtools::document()

It creates or updates the .Rd help files in man/ and the NAMESPACE. Do not edit either generated file by hand. Change the roxygen block and run devtools::document() again.

Use @param for every public argument, @return for every public result, and @examples for a small call that runs without private data or network access. Add @export only when callers should use the function. For a dependency, put @importFrom package function above the function that uses it. This keeps the dependency visible at the point of use.

testthat is the unit testing standard for R in this project. Keep a test file for each public behavior under tests/testthat/.

geneTools/
R/
counts.R
tests/
testthat/
test-counts.R
man/ # generated by roxygen2
DESCRIPTION
NAMESPACE # generated by roxygen2
test_that("CountsPerMillion preserves a total of one million", {
output <- CountsPerMillion(c(25, 75))
expect_equal(sum(output), 1e6)
expect_equal(output, c(250000, 750000))
})

Run the suite during development with devtools::test(). Run devtools::check() before a release. The Testing and Assertions lesson covers known answers, invariants, edge cases, and deterministic random tests.

Before merging a public R function, check the following:

Check Required action
Name Use BigCamelCase for public functions.
Inputs Validate assumptions and document each argument with @param.
Result State the returned type and meaning with @return.
Dependencies Use package::function() and the matching @importFrom tag.
Example Include a small, executable @examples call.
Tests Add a testthat test for the public behavior.
Generated files Run devtools::document() and commit the changed man/ and NAMESPACE files.

Read Testing and Assertions for the test suite that protects this documented API. The roxygen2 reference lists the available tags and package documentation patterns.