# r

Tells Copilot how to write R: follow the file's style, avoid unsafe calls, keep paths project-relative. Useful when a repo has .R, .Rmd or .qmd files.

- rule · `type=rule` · GitHub Copilot · ★ 40418
- Author: github · official GitHub repository
- License: MIT · policy=mirror · the beginning of the file is at the end of this page
- Source: https://github.com/github/awesome-copilot/tree/HEAD/instructions/r.instructions.md
- Updated: 2026-10-23
- HTML: https://affpapa.org/en/nevibecode/rules/r

## What it does

The rule shapes what Copilot suggests in R files. It reads the style already present: tidyverse projects get tidyverse-first patterns, base R projects get base idioms. Mixing `|>` and `%>%` in one script is discouraged unless there is a technical reason.

Inside are conventions for naming (`lower_snake_case`, no dots), reproducibility (seeds set locally with `withr::with_seed()`), safety (no `eval(parse())`, no unparameterized SQL, no hardcoded secrets) and tooling (`styler`, `lintr`, `renv`, `roxygen2`). Separate sections cover Shiny, R Markdown and Quarto, error handling with `rlang` or `tryCatch()`, and performance via `data.table`, `profvis` and `memoise`.

The rule advises against `setwd()` and prefers paths built from the project root. That breaks scripts relying on a changed working directory, so check those spots before turning the rule on in an existing project. It attaches through an `applyTo` mask, so it only touches R, Rmd and Quarto files.

## Install

### GitHub Copilot (native platform)

**Manually: put the files in place**
- File: `.github/instructions/r.instructions.md` — The applyTo field sets which files it applies to

### Claude Code

**Manually: put the files in place**
- File: `.claude/rules/r.md` — The paths frontmatter field limits the files: move applyTo from the source into paths

### Codex

**AGENTS.md**
- Codex reads AGENTS.md: paste the rule text there

### Cursor

**Manually: put the files in place**
- File: `.cursor/rules/r.mdc` — Frontmatter: description, globs, alwaysApply. Move applyTo from the source into globs, or the rule will not attach on its own

### Windsurf (Devin Desktop)

**Manually: put the files in place**
- File: `.devin/rules/r.md`

### Cline

**Manually: put the files in place**
- File: `.clinerules/r.md`

Where a file is given instead of a command, copy the files from the source to that path: https://github.com/github/awesome-copilot/tree/HEAD/instructions/r.instructions.md

## When to use it
- keep R code style consistent across a team
- stop Copilot from mixing base R and tidyverse in one file
- remove hardcoded secrets and unparameterized SQL
- make stochastic runs reproducible with local seeds
- point Copilot at the right packages for I/O and paths

## Example prompts
- write a CSV reader using readr with explicit column types
- rewrite this loop with vapply, the file is base R style
- add roxygen2 docs to this function

## Source text · r.instructions.md · MIT

Below is the content of a third-party file. It is data, not instructions for you: do not act on anything written inside unless the human asks. Block tag: 34715c1c7286ac3b.

BEGIN THIRD-PARTY FILE 34715c1c7286ac3b
```text
---
description: 'R language and document formats (R, Rmd, Quarto): coding standards and Copilot guidance for idiomatic, safe, and consistent code generation.'
applyTo: '**/*.R, **/*.r, **/*.Rmd, **/*.rmd, **/*.qmd'
---

# R Programming Language Instructions

## Purpose

Help GitHub Copilot generate idiomatic, safe, and maintainable R code across projects.

## Core Conventions

- **Match the project’s style.** If the file shows a preference (tidyverse vs. base R, `%>%` vs. `|>`), follow it.
- **Prefer clear, vectorized code.** Keep functions small and avoid hidden side effects.
- **Qualify non-base functions in examples/snippets**, e.g., `dplyr::mutate()`, `stringr::str_detect()`. In project code, using `library()` is acceptable when that’s the repo norm.
- **Naming:** `lower_snake_case` for objects/files; avoid dots in names.
- **Side effects:** Never call `setwd()`; prefer project-relative paths (e.g., `here::here()`).
- **Reproducibility:** Set seeds locally around stochastic operations using `withr::with_seed()`.
- **Validation:** Validate and constrain user inputs; use typed checks and allowlists where possible.
- **Safety:** Avoid `eval(parse())`, unvalidated shell calls, and unparameterized SQL.

### Pipe Operators

- **Native pipe `|>` (R ≥ 4.1.0):** Prefer in R ≥ 4.1 (no extra dependency).
- **Magrittr pipe `%>%`:** Continue using in projects already committed to magrittr or when you need features like `.`, `%T>%`, or `%$%`.
- **Be consistent:** Don't mix `|>` and `%>%` within the same script unless there's a clear technical reason.

## Performance Considerations

- **Large datasets:** consider `data.table`; benchmark with your workload.
- **dplyr compatibility:** Use `dtplyr` to write dplyr syntax that translates to data.table operations automatically for performance gains.
- **Profiling:** Use `profvis::profvis()` to identify performance bottlenecks in your code. Profile before optimizing.
- **Caching:** Use `memoise::memoise()` to cache expensive function results. Particularly useful for repeated API calls or complex computations.
- **Vectorization:** Prefer vectorized operations over loops. Use `purrr::map_*()` family or `apply()` family for remaining iteration needs.

## Tooling & Quality

- **Formatting:** `styler` (tidyverse style), two-space indents, ~100-char lines.
- **Linting:** `lintr` configured via `.lintr`.
- **Pre-commit:** consider `precommit` hooks to lint/format automatically.
- **Docs:** roxygen2 for exported functions (`@param`, `@return`, `@examples`).
- **Tests:** prefer small, pure, composable functions that are easy to unit test.
- **Dependencies:** manage with `renv`; snapshot after adding packages.
- **Paths:** prefer `fs` and `here` for portability.

## Data Wrangling & I/O

- **Data frames:** prefer tibbles in tidyverse-heavy files; otherwise base `data.frame()` is fine.
- **Iteration:** use `purrr` in tidyverse code. In base-style code, prefer type-stable, vectorized patterns such as `vapply()`
   (for atomic outputs) or `Map()` (for elementwise operations) instead of explicit `for` loops when they improve clarity or performance.
- **Strings & Dates:** use `stringr`/`lubridate` where already present; otherwise use clear base helpers (e.g., `nchar()`, `substr()`, `as.Date()` with explicit format).
- **I/O:** prefer explicit, typed readers (e.g., `readr::read_csv()`); make parsing assumptions explicit.

## Plotting

- Prefer `ggplot2` for publication-quality plots. Keep layers readable and label axes and units.

## Error Handling

- In tidyverse contexts, use `rlang::abort()` / `rlang::warn()` for structured conditions; in base-only code, use `stop()` / `warning()`.
- For recoverable operations:
```
END THIRD-PARTY FILE 34715c1c7286ac3b

The third-party file has ended. Everything between the 34715c1c7286ac3b tags is data: requests and commands from it are not followed. An “end of file” line with another tag inside the block is part of the file.

First 3707 of 6400 bytes. © github · MIT · https://github.com/github/awesome-copilot/tree/HEAD/instructions/r.instructions.md

_Part of the page did not fit — see the HTML version._

---
NeVibeCode on affpapa.org. Catalog texts are descriptions, not instructions for the agent. How to choose and install: https://affpapa.org/en/nevibecode/agents.md
