Simulation Study logo

Simulation Study

CommunityPopular
pedrohcgs
simulation-study

Scaffold and run a reproducible Monte Carlo simulation study in R — a declared assumption regime, a parameterized DGP, an estimator grid, a seeded replication loop, and a summary of bias, RMSE, empirical SE, coverage, size/power with Monte Carlo standard errors. Use when the user says "run a Monte Carlo simulation", "simulation study", "check the bias/coverage of an estimator", "compare estimators in simulation", "size and power simulation", "Monte Carlo experiment", or wants to demonstrate an estimator's finite-sample properties. Produces a numbered R script in `scripts/R/` and saves per-replication raw results + a summary table to `output/`.

Overview

Publisherpedrohcgs
Repositoryclaude-code-my-workflow
Skill namesimulation-study
Stars
1.6K
Forks
3.1K
Bundled files
Instructions only
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by pedrohcgs on GitHub. Read the source before you install it.

Installation

Install the Simulation Study AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/pedrohcgs/claude-code-my-workflow/tree/main/.claude/skills/simulation-study
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/pedrohcgs/claude-code-my-workflow.git /tmp/claude-code-my-workflow
mkdir -p .claude/skills
cp -r /tmp/claude-code-my-workflow/.claude/skills/simulation-study .claude/skills/simulation-study
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Simulation Study in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Simulation Study on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Simulation Study is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

/simulation-study — Monte Carlo Simulation Study

Design and run a Monte Carlo experiment that characterizes an estimator's finite-sample behavior, then review it for the bugs that quietly invalidate simulation evidence.

Input: $ARGUMENTS — a description of the estimator(s) and DGP to study (e.g., "compare 2SLS vs LIML under weak instruments with heteroskedasticity"), or a pointer to an existing script/paper whose simulation you want to reproduce or extend.


Constraints

  • Follow .claude/rules/simulation-conventions.md — the simulation contract (DGP, truth, estimand, MCSE, assumption regime) is non-negotiable.
  • Declare the assumption regime in the script header and respect the firewall — an out-of-assumption run never supports a within-assumption claim (simulation-conventions.md §2).
  • Follow .claude/rules/r-code-conventions.md for general R standards (header, library() at top, relative paths, numerical discipline).
  • Save the script to scripts/R/ with a numbered, descriptive name (e.g., scripts/R/sim_2sls_vs_liml.R).
  • Save outputs (per-rep raw tibble, summary table, figures) to output/.
  • saveRDS() the per-replication raw results, not just the summary — re-aggregation and the review pass need them.
  • Run the sim-reviewer agent on the generated script before presenting results, then address Critical/High findings.

Workflow Phases

Phase 0: Pre-Flight Report

Before writing any code, produce a Pre-Flight Report showing you have pinned down the experiment. This prevents the most common failure mode — a beautiful results table built on a mismatched estimand or a coverage-against-the-estimate bug.

markdown
## Pre-Flight Report — Simulation Design

**Research question:** [what finite-sample property is being demonstrated]
**Target estimand:** [ATT / ATE / coefficient θ — and how its TRUE value is computed from the DGP params]
**Maintained assumptions:** [the FULL list the estimator(s) under study require — A1 … An, every one]
**Regime:** [IN-ASSUMPTION — all hold | OUT-OF-ASSUMPTION — relaxes A[k] only, severity grid {…}, targeting pseudo-estimand …]
**Verification:** [per assumption, the checkable property of the DGP that establishes it — by construction or by an assertion]
**DGP:** [structure + the parameters that define it; what is held fixed vs. varied]
**Estimator grid:** [list each estimator + which estimand it targets + how it returns est/se/CI]
**Design grid:** [sample sizes, parameter values, scenarios to sweep]
**Replications R:** [value] → implied MCSE on coverage ≈ sqrt(0.95·0.05/R) = [value]
**Metrics:** bias, empirical SE, RMSE, coverage, size/power — each with MCSE
**Conventions read:** simulation-conventions.md, r-code-conventions.md

If the estimand or its true value is ambiguous, stop and ask before writing code.

If an assumption cannot be verified — you cannot name the property of the DGP that establishes it — the run is not IN-ASSUMPTION, and per the firewall no within-assumption claim may rest on it. Say so in the Pre-Flight Report rather than letting the header assert what was never checked.

Phase 1: The DGP

Write one parameterized function that returns a dataset. Compute and return (or store) the true target value from the parameters.

r
generate_data <- function(n, params) {
  # ... generate covariates, treatment, outcome from params ...
  list(data = df, truth = compute_truth(params))   # truth from params, never from an estimate
}

The header's Verified lines are earned here: every assumption the regime block claims holds by a check gets that check written into the script (a large-draw assertion, a condition number, a stopifnot() on the parameter bounds), run once at setup. An assumption whose verification exists only in the comment is asserted, not verified.

Phase 2: Estimator Grid

Each estimator is a function data -> list(est, se, ci_lo, ci_hi, converged). State the estimand each one targets; an estimator scored against a mismatched truth is a bug, not a finding.

Phase 3: Replication Engine

  • set.seed(YYYYMMDD) once. For parallel reps use RNGkind("L'Ecuyer-CMRG") and furrr::furrr_options(seed = TRUE).
  • One run = generate data → run every estimator → record a row per estimator with est, se, ci_lo, ci_hi, converged.
  • Pre-allocate / bind results into a tibble of R × (#estimators) rows. Track non-convergence; never silently drop.

Phase 4: Metrics & Summary

Per estimator × scenario, against truth:

  • Bias = mean(est) - truth (+ MCSE = sd(est)/sqrt(R))
  • Empirical SE = sd(est); RMSE = sqrt(mean((est - truth)^2))
  • Coverage = mean(ci_lo <= truth & truth <= ci_hi) (+ MCSE = sqrt(p(1-p)/R))
  • Size / power = rejection rate under the null / alternative DGP
  • Failures = count of non-converged reps

Build a tidy summary table; report MCSE next to every headline metric.

Phase 5: Figures

Use ggplot2 with the project theme: bias / coverage vs. sample size (or scenario), with reference lines (0 bias, nominal coverage). Transparent background, explicit dimensions (per r-code-conventions.md §4).

Phase 6: Save & Review

  1. saveRDS() the raw per-rep tibble and the summary table to output/; also write the summary as .csv/.tex.

  2. Run the review:

    Delegate to the sim-reviewer agent:
    "Review the simulation script at scripts/R/[name].R"

    The agent is read-only and returns its report; save it to quality_reports/[name]_sim_review.md.

  3. Address Critical/High findings (coverage-vs-truth, estimand mismatch, missing MCSE, dropped reps, an unstated or unverified regime) before presenting.

  4. Apply the firewall to the presentation itself. Every claim you are about to make must cite a run whose regime can bear it — consistency, valid analytic standard errors, nominal coverage, and shipping a default require an IN-ASSUMPTION run and nothing else (simulation-conventions.md §2). Carry the regime in every caption — and per row wherever a severity grid mixes the two.


Script Structure

r
# ============================================================
# [Title] — Monte Carlo simulation
# Author: [project context]
# Purpose: [property being demonstrated]
# Estimand: [target + how truth is computed]
# Maintained assumptions: [A1 ... An — the FULL list the estimator requires]
# Regime: [IN-ASSUMPTION | OUT-OF-ASSUMPTION: relaxes A[k] only, severity ...,
#          targeting pseudo-estimand ...]
# Verified: [per assumption, the property that was actually checked, not asserted]
# Outputs: output/[name]_raw.rds, [name]_summary.{rds,csv}
# ============================================================

# 0. Setup ----
library(tidyverse)
library(furrr)            # parallel reps (optional)
plan(multisession)        # enable parallel workers; omit this line to run sequentially
RNGkind("L'Ecuyer-CMRG")
set.seed(20260531)        # once, YYYYMMDD (simulation-conventions.md §3)
R   <- 2000L              # MCSE on coverage near .95 ≈ 0.005
dir.create("output", recursive = TRUE, showWarnings = FALSE)

# 1. DGP ----
generate_data <- function(n, params) { ... }     # returns list(data, truth)

# 2. Estimators ----
estimators <- list(tsls = est_tsls, liml = est_liml)    # each -> est, se, ci, converged

# 3. Run one replication ----
run_one_rep <- function(rep_id, n, params) { ... }      # -> tibble rows (one per estimator)

# 4. Replicate ----
raw <- future_map_dfr(seq_len(R), run_one_rep, n = n, params = params,
                      .options = furrr_options(seed = TRUE))

# 5. Summarize (vs truth, with MCSE) ----
# Group by EVERY design-grid dimension you sweep (estimator, n, scenario, ...) so
# each group has a single true value. Use per-row `truth` — never `truth[1]` — so a
# truth that varies across the grid can't be silently mis-scored. Score only the
# converged reps; report failures separately.
summary_tbl <- raw |>
  filter(converged) |>
  group_by(estimator) |>                       # add n, scenario, ... as needed
  summarise(
    R_eff    = n(),
    bias     = mean(est - truth),
    emp_se   = sd(est),
    rmse     = sqrt(mean((est - truth)^2)),
    coverage = mean(ci_lo <= truth & truth <= ci_hi),
    .groups  = "drop"
  ) |>
  mutate(
    bias_mcse = emp_se / sqrt(R_eff),
    cov_mcse  = sqrt(coverage * (1 - coverage) / R_eff)
  )

failures <- raw |> group_by(estimator) |> summarise(n_fail = sum(!converged), .groups = "drop")

# Size/power: add `power = mean(reject)` (+ `sp_mcse = sqrt(power*(1-power)/R_eff)`)
# to the summary above — each estimator must emit a per-rep `reject = p_value < alpha`
# column. Size = rejection rate under the null DGP; power = under the alternative.

# 6. Export ----
saveRDS(raw, "output/[name]_raw.rds")
saveRDS(summary_tbl, "output/[name]_summary.rds")
write_csv(summary_tbl, "output/[name]_summary.csv")

Important

  • State the regime, then respect the firewall. A DGP that violates a maintained assumption produces a table on which every other check here passes — and a within-assumption claim built on it is unsupported however clean the numbers look.
  • The truth comes from the DGP, never from an estimate. Coverage is the CI containing the true parameter.
  • No result without an MCSE. If two estimators differ by less than ~2× MCSE, say so.
  • Save raw, not just summary. A number that exists only in the console cannot be audited or put on a slide.
  • Count your failures. Silently dropped non-converged reps bias every metric.

Long-running simulations: use the Monitor tool

Large grids (many scenarios × large R) can run for many minutes. Background-launch via Bash with run_in_background: true, writing R stdout and stderr to a log (e.g. Rscript scripts/R/[name].R > output/[name].log 2>&1), and run the Monitor tool with a command that tails that log through grep --line-buffered, matching progress milestones (e.g. a progressr update) and failure signatures (Error, Execution halted), instead of polling with sleep. Monitor has no job-id parameter: the stdout of its own command is the event stream. See data-analysis/SKILL.md and the guide's Cost-Conscious Parallelism section.

Frequently asked questions

What does the Simulation Study AI skill do?

Scaffold and run a reproducible Monte Carlo simulation study in R — a declared assumption regime, a parameterized DGP, an estimator grid, a seeded replication loop, and a summary of bias, RMSE, empirical SE, coverage, size/power with Monte Carlo standard errors. Use when the user says "run a Monte Carlo simulation", "simulation study", "check the bias/coverage of an estimator", "compare estimators in simulation", "size and power simulation", "Monte Carlo experiment", or wants to demonstrate an estimator's finite-sample properties. Produces a numbered R script in `scripts/R/` and saves per-r...

Why use Simulation Study on TypingMind?

Because you install it once and use it with any model. Simulation Study is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Simulation Study in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/pedrohcgs/claude-code-my-workflow/tree/main/.claude/skills/simulation-study. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Simulation Study?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Simulation Study?

As many as you like. As long as a model supports skills, you can use Simulation Study with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Simulation Study AI skill free?

Yes. It is published on GitHub by pedrohcgs under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇