Install the "rlang-patterns" agent skill from https://github.com/ab604/claude-code-r-skills/tree/main/.claude/skills/rlang-patterns into .claude/skills/rlang-patterns/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "rlang-patterns", then confirm the skill loads.
Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
Type this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
skills CLI
$ npx skills add ab604/claude-code-r-skills --skill rlang-patterns -a codex
Project install goes to .agents/skills/; add -g for ~/.codex/skills/.
Install the "rlang-patterns" agent skill from https://github.com/ab604/claude-code-r-skills/tree/main/.claude/skills/rlang-patterns into .agents/skills/rlang-patterns/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "rlang-patterns", then confirm the skill loads.
Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
skills CLI
$ npx skills add ab604/claude-code-r-skills --skill rlang-patterns -a cursor
Project install goes to .agents/skills/; add -g for ~/.cursor/skills/.
Install the "rlang-patterns" agent skill from https://github.com/ab604/claude-code-r-skills/tree/main/.claude/skills/rlang-patterns into .cursor/skills/rlang-patterns/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "rlang-patterns", then confirm the skill loads.
Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
skills CLI
$ npx skills add ab604/claude-code-r-skills --skill rlang-patterns -a gemini-cli
Project install goes to .agents/skills/; add -g for ~/.gemini/skills/.
Install the "rlang-patterns" agent skill from https://github.com/ab604/claude-code-r-skills/tree/main/.claude/skills/rlang-patterns into .gemini/skills/rlang-patterns/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "rlang-patterns", then confirm the skill loads.
Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
Installs for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
skills CLI
$ npx skills add ab604/claude-code-r-skills --skill rlang-patterns -a github-copilot
Project install goes to .agents/skills/; add -g for ~/.copilot/skills/.
Install the "rlang-patterns" agent skill from https://github.com/ab604/claude-code-r-skills/tree/main/.claude/skills/rlang-patterns into .github/skills/rlang-patterns/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "rlang-patterns", then confirm the skill loads.
GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
skills CLI
$ npx skills add ab604/claude-code-r-skills --skill rlang-patterns -a opencode
OpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
Install the "rlang-patterns" agent skill from https://github.com/ab604/claude-code-r-skills/tree/main/.claude/skills/rlang-patterns into .opencode/skills/rlang-patterns/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "rlang-patterns", then confirm the skill loads.
OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
Facts
Skill name
rlang-patterns
GitHub stars
206
Used in
2 other repos
Token cost
~2.1k tokens
SKILL.md length
220 words
Files
1
Skills in repo
8
Repo updated
First seen
Licence
MIT
At a glance
rlang metaprogramming patterns for data-masking, injection operators, and dynamic dots.
Writing functions that use tidy evaluation
SKILL.md covers Core Concepts, Function Argument Patterns, Injection Operators and Dynamic Dots Patterns, plus 4 more sections
Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md
What it does
Rlang Patterns is an agent skill from ab604/claude-code-r-skills. rlang metaprogramming patterns for data-masking, injection operators, and dynamic dots. Use when writing functions that use tidy evaluation.
Its SKILL.md is about 2.1k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
The repository describes itself as: Claude Code configurations for R development. The licence is MIT.
When your agent uses it
Writing functions that use tidy evaluation
Example prompts
“/rlang-patterns”
What it can do on your machine
Read from SKILL.md and the folder at commit 529de4f. It shows what the files ask for, not the result of running them.
Tool permissions
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Runs code
No scripts in the folder and no shell commands in SKILL.md (its code samples are r).
From the folder's file list and the shell code blocks in SKILL.md.
Network
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Credentials
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Context cost
Rlang Patterns loads about 2.1k tokens when it runs. Until then it costs about 39 tokens; SKILL.md has 220 words of instructions outside code blocks.
Always· name and description, kept in context so the agent knows when to use it
~39
When it runs· the whole SKILL.md, loaded when a task matches
~2.1k
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
Safety
Auto-check: notes
The automated check noted patterns worth knowing about, such as sudo or a known installer.
NoteMentions a .env fileSKILL.md:20
- **Pronouns `.data`/`.env`** - Explicit disambiguation between data and environment variables
NoteMentions a .env fileSKILL.md:166
### `.data` and `.env` Best Practices
NoteMentions a .env fileSKILL.md:174
env_cyl = mean(.env$cyl), # Environment variable
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
Download SKILL.mdSave it as .claude/skills/rlang-patterns/SKILL.md (or your agent's skills folder).
name
rlang-patterns
description
rlang metaprogramming patterns for data-masking, injection operators, and dynamic dots. Use when writing functions that use tidy evaluation.
Modern rlang Patterns for Data-Masking
Metaprogramming framework that powers tidyverse data-masking
Core Concepts
Data-masking allows R expressions to refer to data frame columns as if they were variables in the environment. rlang provides the metaprogramming framework that powers tidyverse data-masking.
Key rlang Tools
Embracing {{}} - Forward function arguments to data-masking functions
Injection !! - Inject single expressions or values
Splicing !!! - Inject multiple arguments from a list
Dynamic dots - Programmable ... with injection support
Pronouns .data/.env - Explicit disambiguation between data and environment variables
Function Argument Patterns
Forwarding with {{}}
Use {{}} to forward function arguments to data-masking functions:
r
# Single argument forwarding
my_summarise <- function(data, var) {
data |> dplyr::summarise(mean = mean({{ var }}))
}
# Works with any data-masking expression
mtcars |> my_summarise(cyl)
mtcars |> my_summarise(cyl * am)
mtcars |> my_summarise(.data$cyl) # pronoun syntax supported
Forwarding ... (No Special Syntax Needed)
r
# Simple dots forwarding
my_group_by <- function(.data, ...) {
.data |> dplyr::group_by(...)
}
# Works with tidy selections too
my_select <- function(.data, ...) {
.data |> dplyr::select(...)
}
# For single-argument tidy selections, wrap in c()
my_pivot_longer <- function(.data, ...) {
.data |> tidyr::pivot_longer(c(...))
}
Names Patterns with .data
Use .data pronoun for programmatic column access:
r
# Single column by name
my_mean <- function(data, var) {
data |> dplyr::summarise(mean = mean(.data[[var]]))
}
# Usage - completely insulated from data-masking
mtcars |> my_mean("cyl") # No ambiguity, works like regular function
# Multiple columns with all_of()
my_select_vars <- function(data, vars) {
data |> dplyr::select(all_of(vars))
}
mtcars |> my_select_vars(c("cyl", "am"))
Injection Operators
When to Use Each Operator
Operator
Use Case
Example
{{ }}
Forward function arguments
summarise(mean = mean({{ var }}))
!!
Inject single expression/value
summarise(mean = mean(!!sym(var)))
!!!
Inject multiple arguments
group_by(!!!syms(vars))
.data[[]]
Access columns by name
mean(.data[[var]])
Advanced Injection with !!
r
# Create symbols from strings
var <- "cyl"
mtcars |> dplyr::summarise(mean = mean(!!sym(var)))
# Inject values to avoid name collisions
df <- data.frame(x = 1:3)
x <- 100
df |> dplyr::mutate(scaled = x / !!x) # Uses both data and env x
# Use data_sym() for tidyeval contexts (more robust)
mtcars |> dplyr::summarise(mean = mean(!!data_sym(var)))
Splicing with !!!
r
# Multiple symbols from character vector
vars <- c("cyl", "am")
mtcars |> dplyr::group_by(!!!syms(vars))
# Or use data_syms() for tidy contexts
mtcars |> dplyr::group_by(!!!data_syms(vars))
# Splice lists of arguments
args <- list(na.rm = TRUE, trim = 0.1)
mtcars |> dplyr::summarise(mean = mean(cyl, !!!args))
Dynamic Dots Patterns
Using list2() for Dynamic Dots Support
r
my_function <- function(...) {
# Collect with list2() instead of list() for dynamic features
dots <- list2(...)
# Process dots...
}
# Enables these features:
my_function(a = 1, b = 2) # Normal usage
my_function(!!!list(a = 1, b = 2)) # Splice a list
my_function("{name}" := value) # Name injection
my_function(a = 1, ) # Trailing commas OK
Name Injection with Glue Syntax
r
# Basic name injection
name <- "result"
list2("{name}" := 1) # Creates list(result = 1)
# In function arguments with {{
my_mean <- function(data, var) {
data |> dplyr::summarise("mean_{{ var }}" := mean({{ var }}))
}
mtcars |> my_mean(cyl) # Creates column "mean_cyl"
mtcars |> my_mean(cyl * am) # Creates column "mean_cyl * am"
# Allow custom names with englue()
my_mean <- function(data, var, name = englue("mean_{{ var }}")) {
data |> dplyr::summarise("{name}" := mean({{ var }}))
}
# User can override default
mtcars |> my_mean(cyl, name = "cylinder_mean")
Pronouns for Disambiguation
.data and .env Best Practices
r
# Explicit disambiguation prevents masking issues
cyl <- 1000 # Environment variable
mtcars |> dplyr::summarise(
data_cyl = mean(.data$cyl), # Data frame column
env_cyl = mean(.env$cyl), # Environment variable
ambiguous = mean(cyl) # Could be either (usually data wins)
)
# Use in loops and programmatic contexts
vars <- c("cyl", "am")
for (var in vars) {
result <- mtcars |> dplyr::summarise(mean = mean(.data[[var]]))
print(result)
}
Programming Patterns
Bridge Patterns
Converting between data-masking and tidy selection behaviors:
r
# across() as selection-to-data-mask bridge
my_group_by <- function(data, vars) {
data |> dplyr::group_by(across({{ vars }}))
}
# Works with tidy selection
mtcars |> my_group_by(starts_with("c"))
# across(all_of()) as names-to-data-mask bridge
my_group_by <- function(data, vars) {
data |> dplyr::group_by(across(all_of(vars)))
}
mtcars |> my_group_by(c("cyl", "am"))
Transformation Patterns
r
# Transform single arguments by wrapping
my_mean <- function(data, var) {
data |> dplyr::summarise(mean = mean({{ var }}, na.rm = TRUE))
}
# Transform dots with across()
my_means <- function(data, ...) {
data |> dplyr::summarise(across(c(...), ~ mean(.x, na.rm = TRUE)))
}
# Manual transformation (advanced)
my_means_manual <- function(.data, ...) {
vars <- enquos(..., .named = TRUE)
vars <- purrr::map(vars, ~ expr(mean(!!.x, na.rm = TRUE)))
.data |> dplyr::summarise(!!!vars)
}
Error-Prone Patterns to Avoid
Don't Use These Deprecated/Dangerous Patterns
r
# Avoid - String parsing and eval (security risk)
var <- "cyl"
code <- paste("mean(", var, ")")
eval(parse(text = code)) # Dangerous!
# Good - Symbol creation and injection
!!sym(var) # Safe symbol injection
# Avoid - get() in data mask (name collisions)
with(mtcars, mean(get(var))) # Collision-prone
# Good - Explicit injection or .data
with(mtcars, mean(!!sym(var))) # Safe
# or
mtcars |> summarise(mean(.data[[var]])) # Even safer
Common Mistakes
r
# Don't use {{ }} on non-arguments
my_func <- function(x) {
x <- force(x) # x is now a value, not an argument
quo(mean({{ x }})) # Wrong! Captures value, not expression
}
# Don't mix injection styles unnecessarily
# Pick one approach and stick with it:
# Either: embrace pattern
my_func <- function(data, var) data |> summarise(mean = mean({{ var }}))
# Or: defuse-and-inject pattern
my_func <- function(data, var) {
var <- enquo(var)
data |> summarise(mean = mean(!!var))
}
Package Development with rlang
Import Strategy
r
# In DESCRIPTION:
Imports: rlang
# In NAMESPACE, import specific functions:
importFrom(rlang, enquo, enquos, expr, !!!, :=)
# Or import key functions:
#' @importFrom rlang := enquo enquos
Documentation Tags
r
#' @param var <[`data-masked`][dplyr::dplyr_data_masking]> Column to summarize
#' @param ... <[`dynamic-dots`][rlang::dyn-dots]> Additional grouping variables
#' @param cols <[`tidy-select`][dplyr::dplyr_tidy_select]> Columns to select
Testing rlang Functions
r
# Test data-masking behavior
test_that("function supports data masking", {
result <- my_function(mtcars, cyl)
expect_equal(names(result), "mean_cyl")
# Test with expressions
result2 <- my_function(mtcars, cyl * 2)
expect_true("mean_cyl * 2" %in% names(result2))
})
# Test injection behavior
test_that("function supports injection", {
var <- "cyl"
result <- my_function(mtcars, !!sym(var))
expect_true(nrow(result) > 0)
})
This modern rlang approach enables clean, safe metaprogramming while maintaining the intuitive data-masking experience users expect from tidyverse functions.
We found 2 copies of this SKILL.md (exact, near-identical or edited) in other folders, from 2 other GitHub owners. This page covers the copy in ab604/claude-code-r-skills, which our catalogue first saw on October 7, 2026.
Rlang Patterns next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
Rlang Patterns compared with similar skills
Skill
Stars
Used in
Tokens
Auto-check
Licence
Repo updated
Rlang Patterns this skillab604/claude-code-r-skills
Detects process injection techniques (MITRE T1055) — including CreateRemoteThread injection, process hollowing, and DLL injection — by analyzing Sysmon Event IDs 8 (CreateRemoteThread) and 10…
Defend AI systems against prompt injection and indirect prompt attacks using input controls, tool permissions, output validation, and isolation boundaries.
Operator approval contract with internal filing notices for agent-drafted outbound messages, hashed drafts, epoch-keyed decisions, durable delivery claims and receipts, and a pre-draft baseline gate.
Detect process injection techniques (T1055) - including DLL injection, process hollowing, and APC injection - by analyzing Sysmon Event IDs 1, 7, 8, 10, and 25 for cross-process memory operations…
Test-driven development workflow for R using testthat. An agent skill from ab604/claude-code-r-skills.
206 GitHub starsUsed in 2 repos~4.8k tokens
Auto-check passed
Questions about Rlang Patterns
What does Rlang Patterns do?
rlang metaprogramming patterns for data-masking, injection operators, and dynamic dots. Rlang Patterns is an agent skill from ab604/claude-code-r-skills. rlang metaprogramming patterns for data-masking, injection operators, and dynamic dots.
When should I use Rlang Patterns?
Rlang Patterns fits situations like: writing functions that use tidy evaluation.
How do I install Rlang Patterns in Claude Code?
Run `npx skills add ab604/claude-code-r-skills --skill rlang-patterns -a claude-code`. Or copy the skill folder (.claude/skills/rlang-patterns in ab604/claude-code-r-skills) into .claude/skills/rlang-patterns in your project. Claude Code loads it when a task matches its description.
How do I install Rlang Patterns in Codex?
Run `npx skills add ab604/claude-code-r-skills --skill rlang-patterns -a codex`. Or copy the skill folder (.claude/skills/rlang-patterns in ab604/claude-code-r-skills) into .agents/skills/rlang-patterns in your project. Codex loads it when a task matches its description.
Can I use Rlang Patterns in Cursor, Gemini CLI or GitHub Copilot?
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add ab604/claude-code-r-skills --skill rlang-patterns -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/rlang-patterns, .gemini/skills/rlang-patterns, .github/skills/rlang-patterns and .opencode/skills/rlang-patterns in your project.
What does Rlang Patterns need to run?
SKILL.md names no scripts, command-line tools or credentials: Rlang Patterns is instructions for the agent only.
Does Rlang Patterns access the network?
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Is Rlang Patterns safe to install?
Our automated static check of SKILL.md found notes only (mentions a .env file), nothing it rates as a warning. It is not a guarantee. Review the folder before installing.
What licence does Rlang Patterns use?
Rlang Patterns is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
How many tokens does Rlang Patterns use?
About 2.1k tokens (SKILL.md is roughly 8.2k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
What are the alternatives to Rlang Patterns?
Skills that share tags, products or a category with Rlang Patterns: Hunting For Process Injection Techniques (mukul975/Anthropic-Cybersecurity-Skills, 34k stars), It Operations (davila7/claude-code-templates, 32k stars), Prompt Injection Defense (sickn33/agentic-awesome-skills, 47k stars) and Dynamic Workflow Mode (affaan-m/ECC, 274k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
Who maintains Rlang Patterns?
ab604 (a GitHub user) maintains it in ab604/claude-code-r-skills, which has 206 GitHub stars. The repository holds 8 skills in this directory. The repository was last updated on September 17, 2026.
Source: ab604/claude-code-r-skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.