Skip to content
Data
Skill

/stata

Use this skill whenever the user asks to run Stata commands, estimate econometric models, work with .dta files, run a .do file, generate Stata output, or do any statistical analysis where Stata is involved. Also trigger when the user mentions Stata variables, Stata syntax, or

From plugin
applied-micro-skills
2717 skills
Install
$ npx -y skills add kennethkhoocy/applied-micro-skills --skill stata --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/stata

Context preview

The summary Claude sees to decide when to auto-load this skill.

Use this skill whenever the user asks to run Stata commands, estimate econometric models, work with .dta files, run a .do file, generate Stata output, or do any statistical analysis where Stata is involved. Also trigger when the user mentions Stata variables, Stata syntax, or

SKILL.md

stata.SKILL.md
name: stata
description: >-
  Use this skill whenever the user asks to run Stata commands, estimate econometric models,
  work with .dta files, run a .do file, generate Stata output, or do any statistical analysis
  where Stata is involved. Also trigger when the user mentions Stata variables, Stata syntax,
  or econometric tasks where Stata is the natural tool, including regressions, IV estimation,
  diff-in-diff, RDD, panel data, clustering, summary statistics, and margins. Stata runs
  through pystata on StataNow 19.5 BE; configure once with stata_setup, then drive everything
  with stata.run() and exchange data directly with pandas. Prefer this skill over subprocess
  calls or .do-file shelling for Stata work, including cases where the user does not say
  pystata.

Stata Skill — pystata on StataNow 19.5 BE

Run Stata entirely through **pystata**, the official Python integration that ships with Stata. Configure the session once, then issue every command — and run every `.do` file — with `stata.run()`. Data crosses between Python and Stata in memory through pandas, so there is no need to write intermediate `.dta` files or read `.log` files unless the user wants them.

The one rule that matters most

**Always execute Stata through pystata.** Both individual commands and entire `.do` files go through `stata.run(...)`. Never launch `StataBE-64.exe` as a subprocess and never run a do-file in batch mode — pystata keeps a single live Stata session in the Python process, gives direct access to data and stored results, and raises real Python exceptions on errors. Running a do-file is just `stata.run('do "path/to/file.do"')`.

Setup

This machine has **StataNow 19.5 BE** at `C:\Program Files\StataNow19`, and it is already on PATH. `pystata` and `stata_setup` are installed for the system Python (3.14). Basic Edition (BE) is the only licensed edition; `"se"` and `"mp"` cannot be initialized.

Configure once per Python process:

import stata_setup
stata_setup.config(r"C:\Program Files\StataNow19", "be")
from pystata import stata

For clean output without the StataCorp splash banner, drive `pystata.config` directly instead:

import sys
sys.path.insert(0, r"C:\Program Files\StataNow19\utilities")
import pystata
pystata.config.init("be", splash=False)
from pystata import stata

`config.init` can run only once per process; to start over, launch a fresh Python process.

Bundled helper (optional)

`scripts/stata_runner.py` removes the boilerplate: it bakes in the path and edition, configures pystata lazily on first use, and wraps command-running, output capture, and data exchange. Reach for it when a script makes several Stata calls.

import os
import sys
sys.path.insert(0, os.path.expanduser("~/.claude/skills/stata/scripts"))
import stata_runner as sr

sr.run("sysuse auto, clear")
log = sr.run("regress price mpg weight, robust", capture=True)
print(log)
print("R-squared:", sr.ereturn()["e(r2)"])

The plain three-line pattern above works just as well; the helper is a convenience, not a requirement.

Running commands

stata.run("""
    sysuse auto, clear
    summarize price mpg weight
    regress price mpg weight i.foreign, robust
""")

`stata.run(cmd, quietly=False, echo=False)` accepts one command or several newline-separated commands. `quietly=True` suppresses output while still storing results; `echo=True` echoes each command line.

Capturing output

Output prints to stdout by default. To capture it as a string, redirect stdout:

import io, contextlib
buf = io.StringIO()
with contextlib.redirect_stdout(buf):
    stata.run("regress price mpg weight, robust")
log = buf.getvalue()

For a persistent `.log` on disk, tee through `set_output_file` — see `references/pystata-api.md`.

Error handling

A failing command **raises `SystemError`**, with a message ending in the Stata return code such as `r(111);`. Catch it directly; there is no log to parse.

try:
    stata.run("regress price nonexistent_var")
except SystemError as e:
    print("Stata error:", e)   # ".. variable nonexistent_var not found  r(111);"

Common codes: `r(111)` variable not found, `r(198)` syntax error, `r(601)` file not found, `r(2000)` no observations.

Data exchange with pandas

Move data in memory — no `.dta` files needed.

import pandas as pd

# pandas -> Stata (replaces the dataset in memory)
stata.pdataframe_to_data(df, force=True)

# Stata -> pandas
df = stata.pdataframe_from_data()                 # whole dataset
prices = stata.pdataframe_from_data(var=["price", "mpg"])
labeled = stata.pdataframe_from_data(valuelabel=True)   # labels, not codes

Named **frames** let several datasets coexist: `stata.pdataframe_to_frame(df, "aux")` and `stata.pdataframe_from_frame("aux")`. `numpy` arrays have the parallel `nparray_*` calls. Full options are in `references/pystata-api.md`.

If the user explicitly wants a `.dta` artifact, write one from Stata (`save "out.dta", replace`) or from pandas (`df.to_stata("out.dta")`).

Reading stored results

After any command the stored results are plain Python dicts:

stata.run("summarize price", quietly=True)
r = stata.get_return()        # {'r(mean)': 6165.26, 'r(N)': 74.0, ...}

stata.run("regress price mpg weight", quietly=True)
e = stata.get_ereturn()       # {'e(N)': 74.0, 'e(r2)': 0.4996, 'e(b)': <ndarray>, ...}

Scalars are floats, macros are strings, and matrices (`e(b)`, `e(V)`) come back as numpy arrays. For single values inside `python:` blocks, the bundled `sfi` module exposes `Scalar`, `Macro`, `Matrix`, and `Data` — see the reference.

Running an existing .do file

stata.run('do "C:/path/to/analysis.do"')

Capture its output with the same `redirect_stdout` pattern if the user wants the log. The do-file shares the live session, so any data or results it leaves behind are immediately reachable from Python.

BE edition constraint

Read more
Ships withapplied-micro-skills

Claude Code and Codex skills for empirical applied-microeconomics research: reproducibility auditing, LLM-assisted classification methods, event studies, data infrastructure (WRDS, Stata, pyfixest), and publication-grade tables, figures, and documents.

Get the whole plugin

Other skills on applied-micro-skills.