If you copy-paste the same function twice, it belongs in a package.
This creates the scaffolding for your package:
DESCRIPTIONNAMESPACER/ directory for code💡 Pro tip: Version control makes collaboration and rollback easier.
Using Git is great — but before you commit anything:
Even private Git repos are not fully secure.
Warning
Never commit:
Use .gitignore to avoid tracking sensitive files:
You can also add .gitattributes or .Rbuildignore to prevent including files in your built package.
📁 DESCRIPTION - Metadata about your package
📁 NAMESPACE - Controls what functions are visible
📁 R/ - All your function files live here
📁 man/ - Auto-generated documentation
Every R package has a DESCRIPTION file — it’s the package’s metadata.
Package: mypackage
Title: What the Package Does (One Line, Title Case)
Version: 0.0.0.9000
Authors@R: person("Your", "Name", email = "you@example.com", role = c("aut", "cre"))
Description: A longer description of what your package does.
License: MIT + file LICENSE
Encoding: UTF-8
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.2.3| Field | What it does |
|---|---|
Package |
The name of your package (must match folder name) |
Title |
One-sentence title (no period) |
Version |
Start with 0.0.0.9000 for dev |
Authors@R |
Who wrote the package |
Description |
Paragraph describing functionality |
License |
Licensing info (e.g., MIT, GPL-3) |
Imports |
Other packages your code uses |
Use Imports: in DESCRIPTION to declare which packages your functions rely on.
Don’t edit it by hand — use usethis::use_package():
This automatically adds to Imports: and avoids typos.
Tip
Only list packages your code depends on directly.
Use Suggests: for things like testing, vignettes, or optional features.
The NAMESPACE tells R what to export to users and what to import from other packages.
Example (auto-generated):
🧠 If it’s not in NAMESPACE, users can’t use it — even if the function exists.
You rarely edit this file directly. Instead, let roxygen handle it.
Use: - @export to add a function - @importFrom dplyr select to import selectively
Then run:
This updates NAMESPACE for you.
Tip
Internal helpers? Leave out @export — they’ll stay private.
Create a new R script:
Then load your package into your session:
This mimics “installing” your package without needing to reinstall each time.
Tip
You’ll see add_numbers() autocomplete in your session now!
✅ Works!
❌ No documentation yet!
💡 Each line starts with
#'and sits directly above the function.
NAMESPACE.Rd file in man/?help lookup✅ Now you’ll see formatted documentation!
✅ Still works!
This creates a data-raw/ folder and a script you can use to clean/load data.
📦 Your data is now accessible via
my_datasetwhen the package is loaded!
Like functions, you can document datasets using roxygen.
Create a new .R file (e.g., R/data-documentation.R) and add:
#' Example dataset: my_dataset
#'
#' This dataset contains example data imported from a CSV.
#'
#' @format A data frame with 100 rows and 5 variables:
#' \describe{
#' \item{col1}{Description of column 1}
#' \item{col2}{Description of column 2}
#' \item{col3}{Description of column 3}
#' }
#' @source Imported from a CSV file.
"my_dataset"💡 The name in quotes at the end (
"my_dataset") must match the object name.
This will create a help file just like for functions.
You now get documentation in the help panel.
check()will catch most common problems before they become bugs.
usethis::use_testthat() for testingusethis::use_github()usethis cheatsheet: https://usethis.r-lib.orgdevtools docs: https://devtools.r-lib.org