R
Included with Lifetime
$97 forever
Execute these commands after EVERY implementation (see AGENT_AUTOMATION module for full workflow).
languageslanguageslanguage
What this skill does
<!-- R:START --> # R Project Rules ## Agent Automation Commands **CRITICAL**: Execute these commands after EVERY implementation (see AGENT_AUTOMATION module for full workflow). ```bash # Complete quality check sequence: Rscript -e 'styler::style_pkg(dry="on")' # Format check Rscript -e 'lintr::lint_package()' # Linting R CMD check . # Full check Rscript -e 'devtools::test()' # All tests # Security audit: Rscript -e 'pak::pkg_deps_explain()' # Dependency check ``` ## R Configuration **CRITICAL**: Use R 4.2+ with modern package development tools. - **Version**: R 4.2+ - **Recommended**: R 4.3+ - **Style Guide**: tidyverse style guide - **Testing**: testthat 3.x - **Documentation**: roxygen2 ### DESCRIPTION File Requirements ``` Package: yourpackage Type: Package Title: Your Package Title Version: 0.1.0 Author: Your Name Maintainer: Your Name <[email protected]> Description: A comprehensive description of what your package does. License: MIT + file LICENSE Encoding: UTF-8 LazyData: true Roxygen: list(markdown = TRUE) RoxygenNote: 7.2.3 Depends: R (>= 4.2) Imports: dplyr (>= 1.1.0), ggplot2 (>= 3.4.0) Suggests: testthat (>= 3.0.0), knitr, rmarkdown VignetteBuilder: knitr ``` ## Code Quality Standards ### Mandatory Quality Checks **CRITICAL**: After implementing ANY feature, you MUST run these commands in order. **IMPORTANT**: These commands MUST match your GitHub Actions workflows to prevent CI/CD failures! ```bash # Pre-Commit Checklist (MUST match .github/workflows/*.yml) # 1. Format check (matches workflow - use dry="on"!) Rscript -e "styler::style_pkg(dry = 'on')" # 2. Lint (MUST pass with no warnings - matches workflow) Rscript -e "lintr::lint_package()" # 3. Run all tests (MUST pass 100% - matches workflow) Rscript -e "devtools::test()" # 4. Check package (matches workflow - strict CRAN checks) R CMD build . R CMD check *.tar.gz --as-cran --no-manual # 5. Check coverage (MUST meet threshold) Rscript -e "covr::package_coverage()" # 6. Build documentation (matches workflow) Rscript -e "devtools::document()" # If ANY fails: ❌ DO NOT COMMIT - Fix first! ``` **If ANY of these fail, you MUST fix the issues before committing.** **Why This Matters:** - Running different commands locally than in CI causes "works on my machine" failures - CI/CD workflows will fail if commands don't match - Example: Using `styler::style_pkg()` locally but `dry='on'` in CI = failure - Example: Missing `--as-cran` flag = CRAN submission fails - Example: Skipping lintr locally = CI catches style violations ### Formatting - Use `styler` for consistent code style - Based on tidyverse style guide - Configuration in `.lintr` file Example `.lintr`: ``` linters: linters_with_defaults( line_length_linter(100), object_name_linter = NULL, cyclocomp_linter(25) ) exclusions: list( "tests/testthat.R" ) ``` ### Documentation - Use roxygen2 for function documentation - All exported functions must be documented - Include examples in documentation Example roxygen2 documentation: ```r #' Process Data #' #' This function processes input data and returns cleaned results. #' #' @param data A data.frame with input data #' @param threshold Numeric threshold value (default: 0.5) #' @param verbose Logical; if TRUE, print progress messages #' #' @return A data.frame with processed data #' @export #' #' @examples #' data <- data.frame(x = 1:10, y = rnorm(10)) #' result <- process_data(data, threshold = 0.7) process_data <- function(data, threshold = 0.5, verbose = FALSE) { if (!is.data.frame(data)) { stop("data must be a data.frame") } if (verbose) { message("Processing data...") } # Implementation return(data) } ``` ### Testing - **Framework**: testthat 3.x - **Location**: `/tests/testthat` directory - **Coverage**: Must meet threshold (80%+) - **File naming**: `test-*.R` for test files Example test structure: ```r # tests/testthat/test-process.R test_that("process_data handles valid input", { data <- data.frame(x = 1:5, y = 1:5) result <- process_data(data) expect_s3_class(result, "data.frame") expect_equal(nrow(result), 5) }) test_that("process_data errors on invalid input", { expect_error( process_data("not a dataframe"), "data must be a data.frame" ) }) test_that("process_data respects threshold parameter", { data <- data.frame(x = 1:10, y = rnorm(10)) result <- process_data(data, threshold = 0.7) expect_true(all(result$y >= 0.7 | result$y <= -0.7)) }) ``` ## Package Development ### Package Structure ``` yourpackage/ ├── DESCRIPTION # Package metadata ├── NAMESPACE # Auto-generated by roxygen2 ├── LICENSE # License file ├── README.md # Package overview ├── NEWS.md # Changelog ├── R/ │ ├── package.R # Package-level documentation │ ├── data.R # Data documentation │ └── functions.R # Function implementations ├── man/ # Auto-generated documentation ├── tests/ │ ├── testthat.R │ └── testthat/ │ ├── test-functions.R │ └── test-data.R ├── data/ # Package data ├── inst/ # Installed files └── vignettes/ # Long-form documentation ``` ### Development Workflow ```r # Load package for development devtools::load_all() # Run tests devtools::test() # Check package devtools::check() # Generate documentation devtools::document() # Build package devtools::build() # Install locally devtools::install() ``` ## Dependencies ### CRAN vs GitHub Packages ```r # From CRAN install.packages("dplyr") # From GitHub devtools::install_github("tidyverse/dplyr") # Specify in DESCRIPTION: Imports: dplyr (>= 1.1.0) Remotes: github::tidyverse/dplyr@main ``` ## Best Practices ### DO's ✅ - **USE** tidyverse principles - **DOCUMENT** all exported functions - **TEST** all functionality - **CHECK** inputs with `stopifnot()` or custom validation - **RETURN** consistent types - **NAMESPACE** use explicit `::` for external functions - **VECTORIZE** operations when possible ### DON'Ts ❌ - **NEVER** use `T` or `F` (use `TRUE` and `FALSE`) - **NEVER** use `attach()` or `<<-` in packages - **NEVER** modify global options - **NEVER** use `library()` inside functions - **NEVER** leave `browser()` or `print()` debug code - **NEVER** assume working directory Example code style: ```r # ✅ GOOD: Proper function structure process_data <- function(data, threshold = 0.5) { # Input validation stopifnot( is.data.frame(data), is.numeric(threshold), threshold >= 0, threshold <= 1 ) # Use explicit namespace result <- dplyr::filter(data, value > threshold) return(result) } # ❌ BAD: Poor practices process_data <- function(data, threshold = 0.5) { library(dplyr) # DON'T load packages in functions! attach(data) # NEVER use attach()! result <- filter(data, value > threshold) # Unclear where filter comes from result <<- result # DON'T use global assignment! print(result) # Don't print inside functions } ``` ## CI/CD Requirements Must include GitHub Actions workflows: 1. **Testing** (`r-test.yml`): - Test on ubuntu-latest, windows-latest, macos-latest - R versions: release, devel - Use R CMD check --as-cran - Upload coverage to Codecov 2. **Linting** (`r-lint.yml`): - Run lintr checks - Check style with styler - Verify roxygen2 documentation 3. **CRAN Check** (`r-cran.yml`): - R CMD check with --as-cran - Verify no NOTEs, WARNINGs, or ERRORs ## Publishing to CRAN ### Pre-Submission Checklist - ✅ All tests passing - ✅ R CMD check --as-cran passes with 0 NOTEs - ✅ Package documentation complete - ✅ NEWS.md updated - ✅ README.md current - ✅ Examples run successfully - ✅ Vignettes build correctly - ✅ Valid LICENSE file - ✅ No submission policy violations ### Submission Process ```r # 1. Final check devtools::check(cran = TRUE) # 2. Build package devtools::build
Related in languages
csharp-expert
IncludedExpert-level C# development with .NET 8+, ASP.NET Core, LINQ, async/await, and enterprise patterns
languages
java-expert
IncludedExpert-level Java development with Java 21+ features, Spring Boot, Maven/Gradle, and enterprise best practices
languages
pcl-expert
IncludedExpert in Persona Control Language (PCL) - language design, compiler architecture, runtime systems, and ecosystem development
languages
php-expert
IncludedExpert-level PHP development with PHP 8+, Laravel, Composer, and modern best practices
languages
rust-expert
IncludedExpert-level Rust development with ownership, lifetimes, async, error handling, and production-grade patterns
languages
go-expert
IncludedExpert-level Go development with Go 1.22+ features, concurrency, standard library, and production-grade best practices
languages