Stop Writing Bad R Code! Claude Code R Skills Fixes Everything
Stop Writing Bad R Code! Claude Code R Skills Fixes Everything
Your AI assistant just generated another data %>% filter(x > 0) while you weren't looking. The sapply() snuck back in. Your test coverage? Don't ask. And that context window—cluttered with half-remembered variable names from three debugging cycles ago—is burning through tokens faster than you can say "budget overrun."
Sound familiar? You're not alone. The dirty secret of AI-assisted R development isn't that large language models can't write code. It's that they write bad R code—outdated patterns, legacy pipes, type-unstable iterations, and enough group_by()/ungroup() pairs to make Hadley Wickham weep.
But what if your AI assistant actually knew modern R? What if it enforced tidyverse best practices automatically, managed your context window strategically, and even adopted scientific skepticism instead of people-pleasing hallucinations?
Enter Claude Code R Skills—a meticulously curated configuration system that transforms Claude Code from a generic code generator into a disciplined R expert. This isn't another chatbot wrapper. It's a complete behavioral framework with skills, rules, commands, agents, and hooks designed specifically for the R ecosystem. And it might just save your sanity (and your API budget).
What Is Claude Code R Skills?
Claude Code R Skills is a curated collection of Claude Code configurations for modern R development, created by ab604 and actively maintained (version 1.2.4 as of April 2026). The repository provides domain-specific knowledge, workflow automation, and behavioral constraints that customize Claude Code's behavior for R programmers.
The project builds on foundations from Sarah Johnson's Modern R Development Guide, Jeremy Allen's Claude Skills Repo, and Affaan Mustafa's Hackathon-winning "Everything Claude Code" framework. It also incorporates Posit's official testing-r-packages skill and statzhero's tidy-r-skill for advanced data manipulation patterns.
Why it's trending now: The R community is at an inflection point. The native pipe (|>) arrived in R 4.1, dplyr 1.1 introduced per-operation grouping with .by, and join_by() replaced the archaic by = c("a" = "b") syntax. Yet most AI assistants are still trained on pre-2021 codebases, generating legacy magrittr pipes and group_by()/ungroup() anti-patterns. Claude Code R Skills bridges this gap by injecting current best practices directly into Claude's context.
But the repository goes deeper than syntax updates. It addresses a fundamental flaw in AI-assisted development: LLMs are optimized to please users, not to be correct. The creator added a scientific reasoning principle to CLAUDE.md that instructs Claude to test hypotheses rather than prove them, maintain healthy skepticism, quantify uncertainty explicitly with Bayesian framing, and never sacrifice accuracy for user satisfaction. This isn't perfect—the author admits it doesn't fully prevent people-pleasing—but it's a genuine attempt to make AI assistance more scientifically rigorous.
The repository supports multiple installation methods (plugin marketplace, project-level, or global user configuration) and works with both Positron and VS Code with the R language server plugin.
Key Features: The Complete Arsenal
Claude Code R Skills organizes its capabilities into six feature types, each serving distinct purposes in the development lifecycle:
Skills (8 public + 1 local) are passive knowledge resources loaded into Claude's context when relevant. The tidyverse-patterns skill covers modern pipes, joins with join_by(), per-operation grouping with .by, and purrr iteration. The rlang-patterns skill handles data-masking, injection operators (!!, !!!), and dynamic dots. For performance work, r-performance covers profiling with profvis, benchmarking with bench, and vctrs for type stability. The r-bayes skill includes brms, DAG validation, multilevel models, and marginaleffects—a rarity in AI coding tools. A local-only r-machine-learning skill covers XGBoost, LightGBM, CatBoost, Elastic Net, ExtraTrees, and ridge stacking from competition-winning implementations.
Commands are active, user-invocable shortcuts prefixed with /. /plan triggers the planner agent (using Opus) for architectural design before any code is written. /tdd enforces test-driven development workflow. /code-review activates the code-reviewer agent for security and quality analysis. /verify runs the full quality gate: build → lint → coverage → review.
Rules are mandatory constraints always active during sessions. The testing rule enforces 80% coverage minimum with testthat Edition 3 patterns. Security rules govern credential handling and data protection. Git-workflow rules standardize commit formats and PR processes.
Agents are specialized sub-agents with limited tool access. The planner uses Opus for deep architectural reasoning. The tdd-guide enforces test-first workflows. The code-reviewer performs focused security and quality audits.
Hooks are event-driven JavaScript scripts for context window management. The suggest-compact hook recommends /compact after 50 tool uses—critical for cost control. pre-compact saves session state before compaction. git-push-warn prevents accidental pushes. These hooks alone can reduce token costs by 30-40%.
Contexts are dynamic system prompt injections via CLI aliases. Launch with claude-research for exploration mode, claude-dev for implementation focus, or claude-review for audit mode.
Use Cases: Where This Actually Shines
1. Migrating Legacy R Codebases
You're inheriting a 2019 Shiny app drowning in %>% pipes, summarise() without .groups, and sapply() calls that return inconsistent types. Instead of manual refactoring, activate Claude Code R Skills and use /plan with the tidyverse-patterns skill. Claude systematically identifies anti-patterns, proposes modern equivalents, and verifies with testthat snapshots that behavior is preserved.
2. Bayesian Statistical Consulting
Most AI assistants generate frequentist code by default or produce naive Bayesian implementations with improper priors. The r-bayes skill instructs Claude to use brms for multilevel models, validate DAGs with ggdag, and report posterior summaries with marginaleffects. Combined with the scientific reasoning principle, Claude will flag when your model is unidentified rather than returning plausible-looking nonsense.
3. High-Stakes Production Pipelines
When your R code moves from analysis to production, the rules system enforces discipline. The security rule prevents credential commits. The testing rule blocks code that drops below 80% coverage. The verify command runs the full quality gate before any commit reaches your main branch. The git-push-warn hook adds a final human checkpoint.
4. Cost-Conscious Freelancing
API costs scale with context window usage. The token optimization settings—using Sonnet as default (60% cost reduction), capping thinking tokens at 10,000 (70% reduction), and auto-compacting at 50% context—transform expensive Claude Code sessions into sustainable workflows. The suggest-compact hook ensures you compact at logical breakpoints, not mid-implementation when you'd lose critical state.
5. Teaching Modern R Practices
Instructors can distribute the plugin to students, ensuring AI assistance reinforces rather than undermines course objectives. No more grading assignments with %>% when you taught |>. The r-style-guide skill enforces consistent naming, spacing, and function design that matches tidyverse conventions.
Step-by-Step Installation & Setup Guide
Prerequisites
Before installation, ensure you have:
- R 4.3+ (required for native pipe
|>and recent tidyverse features) - dplyr 1.1+, purrr 1.0+, tidyr 1.3+, testthat 3.0+
- Claude Code CLI installed and authenticated
For R language server support in VS Code (not needed for Positron users):
# Install required R packages
install.packages(c("languageserver", "lintr", "styler"))
Option 1: Plugin Marketplace (Recommended)
The fastest path with automatic updates:
# Add the R skills marketplace
/plugin marketplace add ab604/claude-code-r-skills
# Install the core R skills plugin
/plugin install r-skills@r-skills
# Optional: Install R language server for VS Code/terminal
/plugin install r-lsp@r-skills
The r-lsp plugin requires the R languageserver package installed above. See r-lsp for detailed configuration.
Option 2: Project-Level Installation
For team consistency or specific project requirements:
# Clone the repository
git clone https://github.com/ab604/claude-code-r-skills.git
# Copy configuration to your R project
cp -r claude-code-r-skills/.claude/ /path/to/your/project/
cp -r claude-code-r-skills/rules/ /path/to/your/project/
cp -r claude-code-r-skills/commands/ /path/to/your/project/
cp -r claude-code-r-skills/agents/ /path/to/your/project/
cp -r claude-code-r-skills/contexts/ /path/to/your/project/
This binds the configuration to your project directory, ensuring all collaborators use identical rules and skills.
Option 3: Global User Configuration
For personal use across all projects:
# Create directory structure
mkdir -p ~/.claude/skills ~/.claude/rules ~/.claude/commands \
~/.claude/agents ~/.claude/contexts
# Copy all feature types to global config
cp -r claude-code-r-skills/.claude/skills/* ~/.claude/skills/
cp -r claude-code-r-skills/rules/* ~/.claude/rules/
cp -r claude-code-r-skills/commands/* ~/.claude/commands/
cp -r claude-code-r-skills/agents/* ~/.claude/agents/
cp -r claude-code-r-skills/contexts/* ~/.claude/contexts/
Context Aliases Setup
Add to ~/.bashrc or ~/.zshrc for mode-specific launches:
# Research mode: thorough exploration before acting
alias claude-research='claude --system-prompt "$(cat ~/.claude/contexts/research.md)"'
# Development mode: implementation focus with TDD defaults
alias claude-dev='claude --system-prompt "$(cat ~/.claude/contexts/dev.md)"'
# Review mode: security and quality audit
alias claude-review='claude --system-prompt "$(cat ~/.claude/contexts/review.md)"'
Reload your shell configuration (source ~/.bashrc or source ~/.zshrc), then launch with claude-research, claude-dev, or claude-review as needed.
Token Optimization Configuration
Create or edit ~/.claude/settings.json:
{
"model": "sonnet",
"env": {
"MAX_THINKING_TOKENS": "10000",
"CLAUDE_AUTOCOMPACT_PCT_OVERRIDE": "50"
}
}
| Setting | Default | Recommended | Impact |
|---|---|---|---|
model |
opus |
sonnet |
~60% cost reduction; handles 80%+ of coding tasks |
MAX_THINKING_TOKENS |
31999 |
10000 |
~70% reduction in hidden thinking cost per request |
CLAUDE_AUTOCOMPACT_PCT_OVERRIDE |
95 |
50 |
Compacts earlier—better quality in long sessions |
Switch to Opus only for deep architectural reasoning: /model opus.
REAL Code Examples from the Repository
The repository includes practical patterns you can use immediately. Here are five essential examples with detailed explanations:
Example 1: Modern Native Pipe and Per-Operation Grouping
# CORRECT: Native pipe with per-operation grouping
# No persistent grouping state, no ungroup() needed
data |>
filter(x > 0) |> # Remove invalid values first
summarise(mean_y = mean(y), .by = category) # Group ONLY for this operation
Why this matters: The legacy approach group_by(x) |> summarise(y) |> ungroup() creates persistent grouping that propagates to subsequent operations, causing subtle bugs. The .by argument (dplyr 1.1+) limits grouping to a single operation. The native pipe |> (R 4.1+) replaces %>% with a base R operator that's faster and doesn't require magrittr dependency.
Example 2: Modern Join Syntax with join_by()
# CORRECT: Explicit join specification with join_by()
# Readable, handles complex conditions, type-safe
inner_join(x, y, by = join_by(a == b))
# For multiple conditions or inequality joins
left_join(
sales,
targets,
by = join_by(product_id == id, date >= start_date, date <= end_date)
)
Why this matters: The old by = c("a" = "b") syntax uses string matching that's error-prone and can't express inequality conditions. join_by() uses data-masking (unquoted column names) with explicit operators, enabling complex rolling joins and overlapping range matches that were previously impossible in dplyr.
Example 3: Type-Stable Iteration with purrr
# CORRECT: Guaranteed double output, never returns list unexpectedly
map_dbl(data, mean) # Explicit output type
# CORRECT: Binding lists of data frames with consistent types
results <- map(files, read_csv) |>
list_rbind() # vctrs-powered, type-safe row binding
# AVOID: Type-unstable, may return vector OR list depending on input
sapply(x, f) # Never use in production code
Why this matters: sapply() is the "silent killer" of R production code. It returns a vector if results are scalar, a matrix if equal-length, and a list otherwise—type instability that breaks downstream code unpredictably. map_dbl() guarantees output type; list_rbind() uses vctrs for proper type promotion and informative errors on incompatible columns.
Example 4: Data-Masking with Embrace for Function Arguments
# CORRECT: Embrace {{ }} for tidy eval in custom functions
my_summary <- function(data, group_var, value_var) {
data |>
summarise(
mean = mean({{ value_var }}, na.rm = TRUE),
n = n(),
.by = {{ group_var }} # Pass grouping variable programmatically
)
}
# Usage: unquoted column names as promised by tidyverse API
my_summary(starwars, species, mass)
Why this matters: The embrace operator {{ }} (pronounced "curly-curly") solves the "quoting problem" that plagued early tidy eval. Users pass unquoted column names naturally; the function receives them as data-masked expressions. Without this, you'd need users to quote with sym() or you'd capture strings that don't work in tidyverse contexts.
Example 5: Scientific Reasoning Principle in CLAUDE.md
# From .claude/CLAUDE.md — Behavioral instruction for Claude
## Scientific Reasoning Principle
We test hypotheses; we never prove them.
When analyzing data or building models:
- Reason from evidence, not from convenience or user expectations
- Maintain healthy skepticism toward apparent patterns
- Quantify uncertainty explicitly, preferring Bayesian framing
- Never tell the user what you think they want to hear at the expense of accuracy
- Flag when data is insufficient for a conclusion
- Distinguish exploratory analysis from confirmatory analysis
Why this matters: This instruction directly addresses a documented failure mode of LLMs—sycophancy, where models reinforce user misconceptions to appear helpful. In statistical work, this is dangerous: a user might "want" significant results, and an unchecked AI might p-hack or misreport uncertainty to deliver them. This principle makes Claude explicitly prioritize accuracy over user satisfaction, a crucial safeguard for data integrity.
Advanced Usage & Best Practices
Strategic Compaction Protocol: The suggest-compact hook recommends /compact after 50 tool uses, but when you compact matters more than that you compact. Always compact after completing research phases, before starting implementation, after debugging milestones, and after failed approaches. Never compact mid-implementation—you'll lose variable names, file paths, and partial state that Claude needs to continue coherently.
Model Selection Strategy: Start every session with Sonnet. It's 60% cheaper and handles 80% of coding tasks. Reserve Opus for three scenarios: initial architectural planning with /plan, complex debugging where standard approaches failed, and deep statistical reasoning (Bayesian model specification, causal inference design). Switch with /model opus and switch back immediately after.
Context Window Hygiene: The doc-blocker hook warns about creating random .md files—a common Claude behavior that bloats context. Combined with the pre-compact state saving, you maintain session continuity without carrying irrelevant files. For long analyses, use /clear between completely unrelated tasks; it's free and instant.
TDD Workflow Discipline: The recommended sequence—claude-research → /plan → claude-dev → /tdd → implement → /verify → claude-review → commit—isn't ceremonial. Each mode switch resets Claude's context appropriately. Research mode reads extensively before acting; dev mode writes first with short responses; review mode actively hunts issues. Skipping mode switches leads to context contamination where research assumptions leak into implementation or review bias is compromised.
Local Skill Development: The r-machine-learning skill demonstrates how to maintain private skills. Fork the repository, add your r-machine-learning/ directory to .claude/skills/, and keep proprietary patterns (competition-winning ensembles, proprietary feature engineering) out of public repos while still benefiting from Claude's skill system.
Comparison with Alternatives
| Feature | Claude Code R Skills | Generic Claude Code | GitHub Copilot | Cursor |
|---|---|---|---|---|
| R-specific knowledge | Deep (tidyverse 1.1+, rlang, vctrs) | Surface-level | Generic, often outdated | Limited |
| Native pipe support | Enforced | Sporadic | Frequently generates %>% |
Inconsistent |
| Test-driven workflow | Built-in /tdd command |
Manual prompting | None | Basic |
| Context management | Hooks for compaction, state saving | Manual /compact only |
N/A | N/A |
| Scientific reasoning | Explicit principle in config | None | None | None |
| Bayesian/statistical depth | Dedicated r-bayes skill |
Superficial | Minimal | Minimal |
| Cost optimization | Token caps, model switching, hooks | Default (expensive) | Fixed subscription | Fixed subscription |
| Custom rules enforcement | Active rules (testing, security, git) | None | None | Basic linting |
| Installation | Plugin marketplace, project, or global | Default CLI only | IDE extension | IDE-based |
| Open source | Yes (MIT) | Proprietary | Proprietary | Proprietary |
The verdict: Generic Claude Code knows R syntax but lacks ecosystem depth. Copilot and Cursor generate code faster but with no quality enforcement, outdated patterns, and zero statistical rigor. Claude Code R Skills is the only solution that combines modern R expertise with systematic workflow discipline and cost control.
FAQ
Q: Do I need to use Positron, or does this work with VS Code?
This works with any editor. The creator uses Positron, but VS Code users can install the R language server plugin via /plugin install r-lsp@r-skills. You'll need the languageserver, lintr, and styler R packages installed.
Q: Will this work with R versions before 4.1?
No, and that's intentional. The native pipe |> requires R 4.1+, and several skills assume dplyr 1.1+ features like .by and join_by(). The repository enforces modern practices; if you're on older R, upgrade first.
Q: How much can I actually save on API costs?
With recommended settings (Sonnet default, 10K thinking tokens, 50% auto-compact), expect 60-70% reduction versus default Opus usage. The suggest-compact hook prevents the most expensive failure mode: context bloat leading to degraded responses and repeated queries.
Q: Can I use only some features, or is it all-or-nothing?
Fully modular. Install individual skills, pick specific rules, or use commands à la carte. The repository is designed for forking and adaptation—"obviously you can fork and adapt any of these to your case-use."
Q: What's the difference between .claude/rules/ and contexts via --system-prompt?
Rules files handle baseline project standards (always active). Contexts layer scenario-specific behavior via CLI aliases. The CLI approach is faster (no tool call), more reliable (system-level authority), and slightly more token-efficient—but requires shell setup. For most users, the difference is marginal.
Q: Does the scientific reasoning principle actually work?
The author is transparent: "This doesn't seem to prevent the 'telling you what it thinks you want to hear' problem entirely, but is hopefully better than nothing." It's a mitigation, not a cure. Always verify statistical conclusions independently.
Q: What's included in the local-only r-machine-learning skill?
It's not in the public repository, but the README describes it: XGBoost, LightGBM, CatBoost, Elastic Net, ExtraTrees, ridge stacking, and stratified cross-validation. Updated based on the WARND competition final model (4-model ridge stacked ensemble, OOF AUC 0.8187).
Conclusion
The R ecosystem has evolved dramatically since 2021—native pipes, per-operation grouping, join_by(), vctrs, and testthat Edition 3. Yet most AI coding tools are stuck in the past, generating legacy patterns that accumulate technical debt with every autocomplete.
Claude Code R Skills is different. It's not a generic model with R syntax bolted on. It's a behavioral framework built by R developers, for R developers, with explicit safeguards against AI sycophancy, systematic cost controls, and enforcement of genuine best practices.
The combination of skills for modern tidyverse, dedicated Bayesian support, TDD workflow commands, and intelligent context management addresses real pain points that generic tools ignore. The scientific reasoning principle—however imperfect—represents a genuine attempt to make AI assistance more rigorous.
My assessment? If you're doing serious R development with AI assistance, this is now the baseline configuration you should start from. Fork it, adapt it, and never let Claude generate %>% again.
Ready to upgrade your R workflow? Install the plugin now: /plugin marketplace add ab604/claude-code-r-skills then /plugin install r-skills@r-skills. Your future self—and your API budget—will thank you.
Tags
Comments (0)
No comments yet. Be the first to share your thoughts!