ワンクリックで
r-package-structure
Understanding R package directory layout, package states, required and optional files, and build configuration patterns
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Understanding R package directory layout, package states, required and optional files, and build configuration patterns
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Bioconductor-specific package submission requirements, BiocCheck validation, version numbering, and review process beyond standard CRAN requirements
Complete guide to CRAN submission including policies, pre-submission checks, common issues, and the submission process
Comprehensive guide to including data in R packages, covering exported data, internal data, raw files, documentation, and CRAN size limits
Complete guide to managing R package dependencies, including Imports vs Suggests, namespace imports, and handling dependencies in code, tests, examples, and vignettes
Automated CI/CD workflows for R packages including R CMD check across platforms, test coverage reporting, and pkgdown deployment
Create professional hexagonal package logos using hexSticker with Google Fonts, proper dimensions, and automated generation scripts
| name | R Package Structure |
| description | Understanding R package directory layout, package states, required and optional files, and build configuration patterns |
This skill covers the fundamental structure of R packages, from directory layout to the five distinct package states. Understanding package structure is critical for proper package development.
R packages exist in five different states throughout their lifecycle:
.tar.gz file created by R CMD build. Single file for distribution..tgz on macOS, .zip on Windows). No source code.library() loads from.library() or loadNamespace().# State transitions:
# Source -> Bundled: R CMD build / devtools::build()
# Bundled -> Binary: R CMD INSTALL --build
# Source/Bundled -> Installed: R CMD INSTALL / install.packages()
# Installed -> In-memory: library() / loadNamespace()
Understanding these states helps you know:
.Rbuildignore)The package metadata file. Every package MUST have this.
Package: mypackage
Title: What the Package Does (One Line, Title Case)
Version: 0.1.0
Authors@R:
person("First", "Last", , "email@example.com", role = c("aut", "cre"),
comment = c(ORCID = "YOUR-ORCID-ID"))
Description: What the package does (one paragraph).
License: MIT + file LICENSE
Encoding: UTF-8
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.3.1
Imports:
dplyr (>= 1.0.0),
rlang (>= 1.0.0)
Suggests:
testthat (>= 3.0.0),
knitr,
rmarkdown
Config/testthat/edition: 3
The namespace file. Controls what your package exports and imports.
CRITICAL: Never edit this file by hand! Use roxygen2 to generate it.
# Generated by roxygen2: do not edit by hand
export(my_function)
exportPattern("^[^\\.]")
importFrom(dplyr,filter)
importFrom(rlang,"%||%")
Directory containing all your R code files. Required if your package has any functions.
Rules for R/ directory:
.R files (case-sensitive on some platforms)R/zzz.R for .onLoad() and .onAttach()R/
├── data.R # Data documentation
├── import-standalone.R # Standalone imported utilities
├── my-package-package.R # Package-level documentation
├── utils.R # Utility functions
├── main-feature.R # Main functionality
└── zzz.R # .onLoad and .onAttach hooks
Directory containing documentation files (.Rd format). Required for packages with documentation.
CRITICAL: Never edit .Rd files by hand! Use roxygen2 to generate them.
man/
├── mypackage-package.Rd # Package overview
├── my_function.Rd # Function documentation
└── my_data.Rd # Data documentation
Contains exported data objects (.rda or .RData files).
# Create with:
usethis::use_data(my_dataset, overwrite = TRUE)
Important details:
.rda format only (use save() with compress = "xz" for best compression)data(my_dataset) or direct referenceR/data.Rdata() callContains all package tests.
tests/
├── testthat/
│ ├── helper-data.R # Test helpers (loaded before tests)
│ ├── setup.R # Setup run before tests
│ ├── test-feature1.R # Test files (must start with "test-")
│ └── test-feature2.R
└── testthat.R # Entry point (loads testthat and runs tests)
Setup with:
usethis::use_testthat(3) # 3rd edition
Long-form documentation and tutorials.
vignettes/
├── articles/ # Articles (not installed with package)
│ └── supplementary.Rmd
└── introduction.Rmd # Vignettes (installed with package)
# Create with:
usethis::use_vignette("introduction")
usethis::use_article("supplementary")
Key differences:
Files to be installed as-is. Only inst/ contents are copied to installation.
inst/
├── CITATION # How to cite the package
├── extdata/ # Example/raw data files
│ ├── example.csv
│ └── sample.json
├── scripts/ # Helper scripts
│ └── setup.R
└── templates/ # Template files
└── report.Rmd
Access inst/ files with:
system.file("extdata", "example.csv", package = "mypackage")
CRITICAL: Do NOT put a DESCRIPTION or NAMESPACE file in inst/ - this will break your package!
Scripts for creating package data objects. Not included in bundle.
data-raw/
├── DATASET.R # Script to create data/DATASET.rda
└── prepare_examples.R # Script for inst/extdata/ files
# Setup with:
usethis::use_data_raw("DATASET")
Pattern:
# data-raw/DATASET.R
library(tidyverse)
DATASET <- read_csv("source.csv") %>%
clean_names() %>%
filter(year >= 2020)
usethis::use_data(DATASET, overwrite = TRUE)
Compiled code (C, C++, Fortran).
src/
├── Makevars # Unix build configuration
├── Makevars.win # Windows build configuration
├── mycode.cpp # Source files
└── RcppExports.cpp # Auto-generated (Rcpp)
Files/directories to exclude from package bundle. Uses regex patterns (NOT glob patterns).
^.*\.Rproj$ # RStudio project files
^\.Rproj\.user$ # RStudio user files
^data-raw$ # Data preparation scripts
^LICENSE\.md$ # Full license (keep LICENSE)
^README\.Rmd$ # Source (keep README.md)
^\.github$ # GitHub-specific files
^_pkgdown\.yml$ # pkgdown config
^docs$ # pkgdown output
^pkgdown$ # pkgdown extras
^\.httr-oauth$ # OAuth credentials
^\.secrets$ # Secrets directory
^\.env$ # Environment files
^cran-comments\.md$ # CRAN submission notes
^revdep$ # Reverse dependency checks
^\.lintr$ # Linter configuration
^\.pre-commit-config\.yaml$ # Pre-commit hooks
Pattern rules:
^ for start, $ for end\. not .usethis::use_build_ignore("pattern")Files to exclude from version control.
# R specific
.Rproj.user
.Rhistory
.RData
.Ruserdata
# Build artifacts
/*.tar.gz
/*.zip
/check/
/revdep/
# Documentation
/docs/
/Meta/
/doc/
# Package specific
.httr-oauth
.secrets/
.env
# OS specific
.DS_Store
Thumbs.db
GitHub-specific files (excluded from bundle via .Rbuildignore).
.github/
├── workflows/
│ ├── R-CMD-check.yaml # CI checks
│ ├── test-coverage.yaml # Code coverage
│ └── pkgdown.yaml # Deploy docs
├── CONTRIBUTING.md
├── ISSUE_TEMPLATE/
└── PULL_REQUEST_TEMPLATE.md
Common confusion: LICENSE, README, NEWS files
# Correct structure:
LICENSE # Machine-readable (CRAN requires this at root)
LICENSE.md # Human-readable (at root, in .Rbuildignore)
inst/CITATION # Citation info (needs to be installed)
README.md # User-facing (at root, included in bundle)
README.Rmd # Source (at root, in .Rbuildignore)
NEWS.md # At root (automatically used by pkgdown)
data/ # Exported data (users can load)
└── dataset.rda
R/sysdata.rda # Internal data (your functions use, users cannot load)
inst/extdata/ # Raw data files (users access via system.file())
└── example.csv
mypackage/
├── DESCRIPTION # Package metadata (required)
├── NAMESPACE # Auto-generated by roxygen2 (required)
├── LICENSE # License file (required for most licenses)
├── README.md # Package overview (highly recommended)
├── NEWS.md # Change log (recommended)
├── .Rbuildignore # Build exclusions
├── .gitignore # Git exclusions
├── mypackage.Rproj # RStudio project (in .Rbuildignore)
├── R/ # R code (required)
├── man/ # Documentation (auto-generated)
├── tests/ # Tests (highly recommended)
├── vignettes/ # Long-form docs (recommended)
├── data/ # Data (if needed)
├── data-raw/ # Data preparation (in .Rbuildignore)
├── inst/ # Installed files (if needed)
├── src/ # Compiled code (if needed)
└── .github/ # GitHub files (in .Rbuildignore)
R/
├── mypackage-package.R # Package docs
├── main.R # Main functions
├── utils.R # Utilities
└── zzz.R # .onLoad if needed
R/
├── mypackage-package.R
├── feature1.R # Grouped by feature
├── feature2.R
├── feature3.R
├── utils.R
├── utils-feature1.R # Feature-specific utils
├── data.R
└── zzz.R
R/
├── mypackage-package.R
├── aaa-imports.R # Package-level imports (aaa = loaded first)
├── class-feature1.R # S3/R6 class definitions
├── feature1-methods.R # Methods for feature1
├── feature1-utils.R # Utilities for feature1
├── feature2-core.R
├── feature2-helpers.R
├── generics.R # Generic function definitions
├── import-standalone-*.R # Standalone imports
├── utils.R
├── data.R
└── zzz.R
Problem: These are auto-generated by roxygen2.
Solution: Always use roxygen2 comments in R files.
# WRONG: Editing man/my_function.Rd directly
# RIGHT: Add roxygen2 comments in R/my_function.R and run devtools::document()
#' My function title
#'
#' @param x Input data
#' @returns Processed output
#' @export
my_function <- function(x) {
# implementation
}
Problem: R/ does not support subdirectories.
Solution: Use file naming conventions instead.
# WRONG:
R/
└── feature1/
├── core.R
└── utils.R
# RIGHT:
R/
├── feature1-core.R
└── feature1-utils.R
Problem: Development files included in package bundle, inflating size.
Solution: Add patterns to .Rbuildignore.
usethis::use_build_ignore("data-raw")
usethis::use_build_ignore(".github")
Problem: Data in inst/extdata/ is for raw files, not R objects.
Solution: Use correct location for data type.
# For R data objects (users can load):
usethis::use_data(my_dataset) # Creates data/my_dataset.rda
# For raw files (users read):
# Put in inst/extdata/example.csv
# Access with system.file("extdata", "example.csv", package = "pkg")
Problem: script.r instead of script.R (matters on Linux).
Solution: Always use uppercase .R for R code files.
# WRONG: R/utils.r
# RIGHT: R/utils.R
Problem: Package too large for CRAN (<5MB total, <1MB per subdirectory).
Solution: Compress data, move examples to inst/extdata/, suggest large dependencies.
# Compress data maximally:
usethis::use_data(dataset, compress = "xz", overwrite = TRUE)
# Check package size:
devtools::build() # Look at .tar.gz size
Problem: API keys, OAuth tokens in package code.
Solution: Use .Rbuildignore and .gitignore, document user-side credential management.
# .gitignore and .Rbuildignore:
.httr-oauth
.secrets
.env
inst/secrets/
Problem: Misunderstanding what inst/ is for.
Solution: Remember: inst/ contents are copied to package root at installation.
# During development:
inst/extdata/file.csv
# After installation:
extdata/file.csv # (inst/ is stripped)
# Access:
system.file("extdata", "file.csv", package = "mypackage")
Problem: Data in data/ but users must call data() to load it.
Solution: Add to DESCRIPTION.
LazyData: true
Problem: Having both README.md and README.Rmd without .Rbuildignore.
Solution: Keep only README.md in bundle.
# Correct setup:
README.Rmd # Source (in .Rbuildignore)
README.md # Generated (included in bundle)
# .Rbuildignore:
^README\.Rmd$
# Create package structure:
usethis::create_package("~/mypackage")
# Setup development tools:
usethis::use_git()
usethis::use_github()
usethis::use_testthat(3)
usethis::use_mit_license()
usethis::use_roxygen_md()
# Configure build:
usethis::use_build_ignore(c("data-raw", ".github"))
usethis::use_data(dataset) # Add exported data
usethis::use_data_raw("dataset") # Create data-raw/ script
usethis::use_r("function") # Create R/function.R
usethis::use_test("function") # Create test file
usethis::use_vignette("intro") # Add vignette
usethis::use_package("dplyr") # Add dependency
usethis::use_build_ignore("file") # Add to .Rbuildignore
# Check overall structure:
devtools::check()
# Build package:
devtools::build()
# Install locally:
devtools::install()
# Check what's in bundle:
pkgbuild::build(path = ".", dest_path = tempdir())
# Then examine .tar.gz contents