r
Use when analysing data with R — monthly time series with seasonality, moving averages and outlier detection, tidy data with dplyr or base R, ggplot2 charts, testthat tests, renv for reproducibility a
SKILL.mdskills/languages/r/SKILL.md
GitHubR
Default: current R release, renv for package versions, scripts run with Rscript, base stats for time series (ts, stl, decompose), ggplot2 for charts, testthat for tests, a rocker/r-ver image pinned to the R version for reproducible runs.
Setup
renv::init()in the project, commitrenv.lock; collaborators runrenv::restore().- Put analysis code in functions under
R/and keep top-level scripts short (Rscript run.R input.csv). - Pin the Docker base image to the same R version as
renv.lock. Automated dependency bots do not readrenv.lock, so let them track the base image tag instead and update packages deliberately.
Monthly time series
- Build a complete monthly index first; missing months must be explicit
NA, not absent rows, or seasonal lags shift. ts(x, frequency = 12, start = c(year, month)), thenstl(x, s.window = "periodic")for trend + seasonal + remainder (needs at least two full years and noNA— impute or trim first).- A centred 2×12 moving average (
stats::filter(x, c(1/24, rep(1/12, 11), 1/24), sides = 2)) shows trend without seasonality; a plain 12-term window is off-centre by half a month. - Flag outliers on the remainder, not the raw series (e.g. |remainder| > 3 × MAD); a winter peak is not an outlier.
- Report each flag with the month, value, expected value and the rule that fired.
Data handling
- Read with explicit column types (
readr::read_csv(col_types = ...)orcolClasses); checkproblems(). - Dates with
as.Date(x, format = "%Y-%m-%d"); avoid locale-dependent month names. - Keep data tidy (one row per observation) before plotting or modelling.
Charts
ggplot2with explicit scales and units in axis titles; save withggsave(width, height, dpi)so output is identical across machines.
Testing
testthatfor functions: complete-index creation, imputation, outlier rule on a synthetic series with a planted spike.- Set seeds (
set.seed) wherever randomness is used, and record them.
Verification loop
Rscript -e 'renv::status()'reports a consistent library.Rscript -e 'testthat::test_dir("tests")'.- Run the script in the pinned container and compare outputs with the local run.
Pitfalls
- Factors from strings: older code and some readers convert strings to factors; check
str(df). NApropagation:mean(x)isNAif any value is missing; decide betweenna.rm = TRUEand imputation explicitly.- 1-based indexing and recycling: vectors of different lengths recycle silently, often with only a warning.
sapplyreturn types change with input; usevapplywith a declared type.- Floating comparisons: use
all.equalor a tolerance, not==.