Install
$ agentstack add skill-yale-som-hpc-claude-code-marketplace-running-r ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Running R
Rule: load R explicitly, restore packages deliberately, and never let package installs happen inside large job arrays.
Tooling defaults
Slightly opinionated picks for new R projects on the cluster:
- Cluster R module for the R executable. Load it explicitly in every job script, and pin the version for reproducibility — pick one from
module spider randmodule load r/, rather than baremodule load r, which follows the moving default. - The base R module ships essentially no add-on packages — not even
renv.optparse,data.table,arrow,tidyverse,here,fixest, etc. are all absent until you install them. Your very first setup step is bootstrapping a project library (see "Use renv carefully"); a job thatlibrary(optparse)without that step will fail withthere is no package called 'optparse'. renvfor project libraries.renv.lockis the R analogue ofuv.lock— it is what makes runs reproducible from login node to compute node.pakas the installer behindrenvfor fast parallel installs.lintr+stylerfor static checks and formatting;testthatfor tests. Install once at project setup.optparsefor CLI scripts (one-file batch entry points like the pattern below).- Native pipe
|>unless you specifically need magrittr's%>%placeholders.
Style defaults
For the audience that is new to R — these are not stylistic preferences, they are the conventions that will make your code readable to anyone who comes after you (including future-you):
snake_casefor variables and functions; reserveCamelCasefor S4/R6 classes.# pin a version frommodule spider r; baremodule load r` follows the moving default
R --version
Do this in job scripts too. Do not assume `R` is in the default PATH. The base module's `.libPaths()` is read-only, so `install.packages()`/`renv` write to a personal or project library — and that first install needs outbound CRAN access from the login node. Do not use `rig` or `mise` as the default R installer on this cluster: R versions are provided by Lmod modules, and user jobs should build reproducibility with `renv` on top of the loaded module.
## Use renv carefully
In the project directory, on the login node:
```r
install.packages("renv")
renv::init()
renv::install(c("data.table", "arrow", "fixest"))
renv::snapshot()
Commit:
renv.lock
.Rprofile
Do not commit renv/library/.
Shared library path
For shared projects, set a project library path in .Rprofile:
Sys.setenv(RENV_PATHS_LIBRARY = "/gpfs/project/myproject/environments/renv/library")
Run renv::restore() once during setup, not inside hundreds of jobs. Mutating the project library inside a Slurm array is a metadata storm and a reproducibility hazard.
Data manipulation defaults
- tidyverse (
dplyr,tidyr,readr) is the right default for ordinary research code — readable, well-documented, easy to share. data.table(ordtplyrfor dplyr syntax with data.table speed) when you have actually benchmarked memory or runtime as the bottleneck, typically on data >1GB or in a hot inner loop. Switch because of measured pain, not as an identity marker.arrow+ Parquet for anything you store on/gpfs/project/...and reuse. One Parquet beats many CSVs for both speed and GPFS metadata health.
Safe R Slurm template
#!/bin/bash
#SBATCH --job-name=r-job
# default_queue caps at 4h; for long/large work use cpunormal or gpunormal (see managing-jobs)
#SBATCH --partition=default_queue
#SBATCH --time=01:00:00
#SBATCH --cpus-per-task=4
#SBATCH --mem=16G
#SBATCH --output=logs/%x_%j.out
set -euo pipefail
module purge
module load r
# The cluster R module is built against OpenBLAS, so OPENBLAS_NUM_THREADS is the
# control that matters; OMP is also honored. MKL_NUM_THREADS is a no-op here
# (no MKL) — kept only for portability.
export OMP_NUM_THREADS=${SLURM_CPUS_PER_TASK:-1}
export OPENBLAS_NUM_THREADS=${SLURM_CPUS_PER_TASK:-1}
export MKL_NUM_THREADS=${SLURM_CPUS_PER_TASK:-1}
cd /gpfs/project/myproject/code
srun Rscript src/main.R
Use srun Rscript (not bare Rscript) for the same reason as Python: signals from --signal=USR1@N reach the job's main process, not just the batch shell.
CLI script pattern
Use an explicit script entry point so batch jobs can pass inputs and outputs.
#!/usr/bin/env Rscript
# Requires `renv::install(c("optparse", "arrow"))` first — neither is in the base
# module. (For zero-dependency scripts, base-R `commandArgs(trailingOnly = TRUE)`
# works out of the box.)
suppressPackageStartupMessages({
library(optparse)
library(arrow)
})
option_list <- list(
make_option(c("-i", "--input"), type = "character"),
make_option(c("-o", "--output"), type = "character")
)
opt <- parse_args(OptionParser(option_list = option_list))
if (is.null(opt$input) || is.null(opt$output)) {
stop("--input and --output are required", call. = FALSE)
}
Prefer clear errors and command-line arguments over editing paths inside scripts.
Read Slurm settings in R
slurm_cpus <- Sys.getenv("SLURM_CPUS_PER_TASK", "")
n_cpus <- if (nzchar(slurm_cpus)) as.integer(slurm_cpus) else parallel::detectCores()
job_id <- Sys.getenv("SLURM_JOB_ID", "local")
message("job_id=", job_id, " n_cpus=", n_cpus)
data.table::setDTthreads(n_cpus)
Resumable output
library(arrow)
output <- "/gpfs/project/myproject/output/task_001.parquet"
if (file.exists(output)) {
message("already done")
quit(save = "no", status = 0)
}
tmp <- paste0(output, ".tmp")
write_parquet(results, tmp)
file.rename(tmp, output)
Avoid
Rscript -e 'renv::restore()' # inside every job: bad
Install/restore once, then run many jobs.
Checklist
- [ ] Job script loads R module explicitly.
- [ ]
renv.lockis committed. - [ ]
renv::restore()is run once at setup, not inside job arrays. - [ ] Batch scripts accept input/output arguments instead of hardcoded paths.
- [ ] BLAS/OpenMP thread variables are set with
${SLURM_CPUS_PER_TASK:-1}. - [ ]
data.table::setDTthreads(n_cpus)matches allocated CPUs. - [ ] Long jobs use
srun Rscript .... - [ ] Outputs are resumable and atomically written.
Further reading
- renv documentation —
init,snapshot,restore, project libraries. - pak — fast parallel package installer.
- tidyverse style guide — the conventions named above, in depth.
- data.table reference —
setDTthreads,fread,:=, joins. - dtplyr — dplyr syntax over data.table.
- Apache Arrow for R —
open_dataset, Parquet I/O, dplyr verbs. - Lmod user guide —
module load r,module purge.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: yale-som-hpc
- Source: yale-som-hpc/claude-code-marketplace
- License: Unlicense
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.