Skip to main content

r-package-structure

Understanding R package directory layout, package states, required and optional files, and build configuration patterns

インストールへ移動

ソース情報

リポジトリ
choxos/RPkgAgent
ソースの最終更新活動
2026年2月15日 21:57
検出された SKILL.md の言語
英語
スター
0
フォーク
0

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
name
R Package Structure
description
Understanding R package directory layout, package states, required and optional files, and build configuration patterns
# R Package Structure ## Overview 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. ## The Five Package States R packages exist in five different states throughout their lifecycle: 1. **Source**: The development state - what you work on. A directory with DESCRIPTION, R/, etc. 2. **Bundled**: A compressed `.tar.gz` file created by `R CMD build`. Single file for distribution. 3. **Binary**: Platform-specific compiled package (`.tgz` on macOS, `.zip` on Windows). No source code. 4. **Installed**: Decompressed into a library directory. What `library()` loads from. 5. **In-memory**: Loaded into R's namespace system via `library()` or `loadNamespace()`. ```r # 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: - What files belong in source but not in bundles (`.Rbuildignore`) - Why some files exist in installed packages but not source - When code executes (build time vs load time) ## Required Files and Directories ### DESCRIPTION The package metadata file. Every package MUST have this. ```dcf 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 ``` ### NAMESPACE The namespace file. Controls what your package exports and imports. **CRITICAL**: Never edit this file by hand! Use roxygen2 to generate it. ```r # Generated by roxygen2: do not edit by hand export(my_function) exportPattern("^[^\\.]") importFrom(dplyr,filter) importFrom(rlang,"%||%") ``` ### R/ Directory containing all your R code files. Required if your package has any functions. **Rules for R/ directory:** - Only `.R` files (case-sensitive on some platforms) - Files sourced in alphabetical order during build - No subdirectories (all files in flat structure) - File names should be descriptive of content - Special file: `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 ``` ### man/ 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 ``` ## Optional Directories ### data/ Contains exported data objects (`.rda` or `.RData` files). ```r # Create with: usethis::use_data(my_dataset, overwrite = TRUE) ``` **Important details:** - Binary `.rda` format only (use `save()` with `compress = "xz"` for best compression) - Accessed by users with `data(my_dataset)` or direct reference - Requires documentation in `R/data.R` - LazyData: true in DESCRIPTION means data loads without `data()` call - CRAN limit: <5MB total, <1MB per subdirectory ### tests/ Contains 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: ```r usethis::use_testthat(3) # 3rd edition ``` ### vignettes/ Long-form documentation and tutorials. ``` vignettes/ ├── articles/ # Articles (not installed with package) │ └── supplementary.Rmd └── introduction.Rmd # Vignettes (installed with package) ``` ```r # Create with: usethis::use_vignette("introduction") usethis::use_article("supplementary") ``` **Key differences:** - Vignettes: Installed with package, in CRAN bundle - Articles: pkgdown only, not in bundle (saves size) ### inst/ 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: ```r system.file("extdata", "example.csv", package = "mypackage") ``` **CRITICAL**: Do NOT put a `DESCRIPTION` or `NAMESPACE` file in `inst/` - this will break your package! ### data-raw/ 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 ``` ```r # Setup with: usethis::use_data_raw("DATASET") ``` **Pattern:** ```r # data-raw/DATASET.R library(tidyverse) DATASET <- read_csv("source.csv") %>% clean_names() %>% filter(year >= 2020) usethis::use_data(DATASET, overwrite = TRUE) ``` ### src/ Compiled code (C, C++, Fortran). ``` src/ ├── Makevars # Unix build configuration ├── Makevars.win # Windows build configuration ├── mycode.cpp # Source files └── RcppExports.cpp # Auto-generated (Rcpp) ``` ## Build Control Files ### .Rbuildignore 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:** - Regex, not glob: use `^` for start, `$` for end - Escape dots: `\.` not `.` - Case-sensitive - Test patterns with `usethis::use_build_ignore("pattern")` ### .gitignore 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/ 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 ``` ## What Goes Where? ### inst/ vs Root Directory **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) ``` ### Internal vs External Data ``` 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 ``` ### Package-level Files ``` 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) ``` ## File Organization Patterns ### Small Package (<10 functions) ``` R/ ├── mypackage-package.R # Package docs ├── main.R # Main functions ├── utils.R # Utilities └── zzz.R # .onLoad if needed ``` ### Medium Package (10-50 functions) ``` 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 ``` ### Large Package (50+ functions) ``` 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 ``` ## Common Pitfalls ### 1. Editing NAMESPACE or .Rd Files Manually **Problem**: These are auto-generated by roxygen2. **Solution**: Always use roxygen2 comments in R files. ```r # 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 } ``` ### 2. Using Subdirectories in R/ **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 ``` ### 3. Forgetting .Rbuildignore for Development Files **Problem**: Development files included in package bundle, inflating size. **Solution**: Add patterns to `.Rbuildignore`. ```r usethis::use_build_ignore("data-raw") usethis::use_build_ignore(".github") ``` ### 4. Putting Data in inst/ Instead of data/ **Problem**: Data in `inst/extdata/` is for raw files, not R objects. **Solution**: Use correct location for data type. ```r # 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") ``` ### 5. Wrong File Extension Case **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 ``` ### 6. Exceeding CRAN Size Limits **Problem**: Package too large for CRAN (<5MB total, <1MB per subdirectory). **Solution**: Compress data, move examples to inst/extdata/, suggest large dependencies. ```r # Compress data maximally: usethis::use_data(dataset, compress = "xz", overwrite = TRUE)
GitHubで見る
この SKILL.md は非常に大きいため、SkillsMP では最初のセクションだけを表示しています。 GitHubで見る