Documenting Functions with roxygen2
Write @param, @return, @examples, and @export tags for automatic docs.
Documenting Functions with roxygen2 is a free R Academy lesson on CoddyKit. This is lesson 2 of 4. Any 3 lessons of this learning path are free to read in full — after that, CoddyKit PRO unlocks every lesson, plus hands-on practice with a built-in code editor and a 24/7 AI tutor. It is part of the R Academy learning path, and your progress syncs across the web and the CoddyKit app. The R Academy course includes 4 lessons in total.
What Is roxygen2?
roxygen2 lets you write R documentation directly above your function as specially formatted comments starting with #'. When you run devtools::document(), roxygen2 parses these comments and generates man/*.Rd files and updates NAMESPACE automatically.
The Minimal roxygen2 Block
The simplest documentation block needs at least a title and description. The first sentence (up to the first period or blank line) becomes the title. Subsequent paragraphs become the description.
# R/add.R
#
# #' Add two numbers
# #'
# #' Computes the sum of x and y. Both arguments must be numeric.
# #'
# #' @export
# add <- function(x, y) {
# x + y
# }@title and @description Tags
Use explicit @title and @description tags when the first-paragraph convention is not enough — for example, when the title must differ from the function name or the description is multi-paragraph.
# #' @title Safe Addition of Numeric Values
# #' @description
# #' Adds two numeric vectors element-wise.
# #' Returns NA where either input is NA.
# #' Useful for financial calculations where NA propagation matters.
# #'
# #' @export
# add <- function(x, y) {
# x + y
# }@param — Documenting Arguments
#' @param name Description documents one function argument. Use one @param line per argument. The description should state the expected type and what the argument controls.
# #' Add two numbers
# #'
# #' @param x A numeric vector. The first operand.
# #' @param y A numeric vector. The second operand. Must be the same length as x
# #' or length 1 (recycled).
# #'
# #' @export
# add <- function(x, y) {
# if (!is.numeric(x) || !is.numeric(y)) stop('x and y must be numeric')
# x + y
# }@return — Documenting the Return Value
#' @return Description describes what the function returns. State the type, class, and structure of the return value. This is required for CRAN submission.
# #' Add two numbers
# #'
# #' @param x A numeric vector.
# #' @param y A numeric vector.
# #' @return A numeric vector of the same length as the longer of x or y,
# #' containing the element-wise sums.
# #'
# #' @export
# add <- function(x, y) x + y@examples — Runnable Code Examples
#' @examples provides code that appears in the help page and is run by R CMD check. Examples must complete in under 5 seconds and not require external resources (network, files). Each line is regular R code — no special prefixes needed.
# #' Add two numbers
# #'
# #' @param x A numeric vector.
# #' @param y A numeric vector.
# #' @return A numeric vector of element-wise sums.
# #' @examples
# #' add(1, 2)
# #' add(c(1, 2, 3), c(10, 20, 30))
# #' add(0, -5)
# #' @export
# add <- function(x, y) x + y@export — Making Functions Public
#' @export tells roxygen2 to add the function to NAMESPACE, making it available to users of your package. Functions without @export are internal — they can be called within the package but not by users (without :::).
# Public function — exported:
# #' @export
# add <- function(x, y) x + y
#
# Internal helper — not exported:
# check_numeric <- function(x) {
# if (!is.numeric(x)) stop('Expected numeric')
# }
#
# After devtools::document(), NAMESPACE will contain:
# export(add)
# but NOT check_numeric@importFrom — Importing Functions
#' @importFrom pkg fn1 fn2 imports specific functions from a package into your namespace so you can call them without the pkg:: prefix. Use sparingly — explicit pkg::fn() is clearer and avoids namespace pollution.
# Option 1 — @importFrom (adds to NAMESPACE, no pkg:: needed):
# #' @importFrom stringr str_trim str_to_lower
# clean <- function(x) str_to_lower(str_trim(x))
#
# Option 2 — explicit :: (recommended for clarity):
# clean <- function(x) {
# stringr::str_to_lower(stringr::str_trim(x))
# }
#
# Both work; prefer Option 2 to keep NAMESPACE minimaldevtools::document() Workflow
After editing roxygen2 comments, call devtools::document() (Ctrl+Shift+D) to regenerate man/*.Rd and update NAMESPACE. Then view the help page with ?add (after load_all()) to confirm it looks correct.
# Full documentation cycle:
# 1. Edit roxygen2 comments in R/add.R
# 2. devtools::document() # regenerate man/ and NAMESPACE
# 3. devtools::load_all() # reload package
# 4. ?add # preview the help page
# 5. devtools::check() # ensure no documentation errorsDocumenting Multiple Functions on One Page
Use #' @rdname shared_name to merge multiple related functions onto a single help page. The primary function gets the full roxygen2 block; secondary functions get only @rdname and @export.
# R/arithmetic.R
#
# #' Basic Arithmetic
# #' @param x,y Numeric vectors.
# #' @return A numeric vector.
# #' @examples
# #' add(1, 2); subtract(5, 3)
# #' @export
# add <- function(x, y) x + y
#
# #' @rdname add
# #' @export
# subtract <- function(x, y) x - yOther Useful Tags
Additional roxygen2 tags for complete documentation:
#' @seealso \code{\link{other_fn}}— cross-reference#' @note— extra notes after description#' @author Name— function author#' @keywords internal— hides from package index but keeps help page#' @family group_name— groups related functions in help
# #' Add two numbers
# #' @param x,y Numeric vectors.
# #' @return Numeric vector.
# #' @seealso \code{\link{subtract}} for the inverse operation.
# #' @family arithmetic
# #' @examples
# #' add(1, 1)
# #' @export
# add <- function(x, y) x + yQuick Check: @export Tag
What happens to a function in an R package that has roxygen2 documentation but NO #' @export tag?
roxygen2 Documentation Recap
Core roxygen2 tags for complete R package documentation:
#' @title/ first line — function title#' @description— detailed description#' @param name Description— document each argument#' @return Description— describe return value#' @examples \n code— runnable examples (checked by R CMD check)#' @export— add to NAMESPACE (makes function public)#' @importFrom pkg fn— import specific functions- Run
devtools::document()to regenerate man/ and NAMESPACE
Learn R with an AI tutor — free
Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.
- Courses
- 43
- Lessons
- 159
Frequently Asked Questions
Is the “Documenting Functions with roxygen2” lesson free?
Yes — any 3 lessons of the R Academy learning path, including “Documenting Functions with roxygen2”, are free to read in full here on the web. After that, CoddyKit PRO unlocks every lesson, plus interactive practice with a built-in code editor and a 24/7 AI tutor. The R Academy course includes 4 lessons in total.
What will I learn in “Documenting Functions with roxygen2”?
Write @param, @return, @examples, and @export tags for automatic docs. You practise R Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start R Academy?
No prior experience is required. R Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 2 of 4.
How long does the “Documenting Functions with roxygen2” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this R Academy lesson?
Yes. Every R Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Package Structure with usethis and devtools
- Documenting Functions with roxygen2
- Unit Testing with testthat
- CRAN Submission and Package Maintenance