Claude
Skills
Sign in
Back

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
Files: 1
Size: 8.3 KB
Complexity: 16/100
Category: languages

Related in languages