AgentStack
SKILL verified MIT Self-run

Stata

skill-kennethkhoocy-applied-micro-skills-stata · by kennethkhoocy

>-

No reviews yet
0 installs
0 views
view→install

Install

$ agentstack add skill-kennethkhoocy-applied-micro-skills-stata

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No 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 Used
  • Environment & secrets No
  • 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.

Are you the author of Stata? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

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)': , ...}

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 constraints

StataNow 19.5 BE differs from SE/MP:

  • Variable ceiling of 2048 (c(maxvar)); SE allows 32,767 and MP up to

120,000. Trim wide datasets with keep/drop before loading, or the load fails.

  • Single computational core for estimation — BE has no MP parallelism, so

very large models run slower.

  • set matsize is irrelevant — it was removed in Stata 16; matrix size is

managed automatically. Do not reintroduce it.

  • Most commands run unchanged in BE; the practical limits are dataset width and

speed, not command availability.

Stata 19 capabilities (absent in the old Stata 16 setup)

Because this is Stata 19, several things the previous version could not do are now available:

  • didregress / xtdidregress for difference-in-differences (introduced in

Stata 17). For the user's applied-micro work, still prefer reghdfe for high-dimensional or staggered-adoption designs; reach for modern estimators (csdid, did_multiplegt) when treatment timing varies.

  • python: blocks inside do-files, with sfi for reading and writing Stata

objects from Python.

  • Frames with full Python integration, as shown above.

Econometric workflow conventions

These reflect the user's applied-microeconomics practice. Follow them unless the user says otherwise.

Standard errors. Default to robust (, robust) for cross-sectional regressions. For panel data, cluster at the unit level (, vce(cluster panelid)). Honor any clustering variable the user specifies. When the clustering level is genuinely ambiguous, ask, because it is a consequential choice.

Estimation. For IV use ivregress and always report the first-stage F-statistic (estat firststage after ivregress 2sls). For high-dimensional fixed effects prefer reghdfe (reghdfe y x, absorb(id year) cluster(id)); for simpler panels xtreg or areg are fine, and always xtset before xtreg.

Output. For side-by-side specifications use esttab from the estout package; do not use outreg2. Display N and R-squared prominently.

Data inspection. On an unfamiliar dataset run describe, summarize, and codebook, compact first, and flag missing values, string-encoded numerics, and duplicate ID values.

User-written commands (reghdfe, ftools, estout, csdid) install with ssc install from inside a stata.run(...) call. Check availability with which before assuming a package is present.

Troubleshooting

| Symptom | Likely cause | Fix | |---|---|---| | FileNotFoundError: ... shared library on init("se"/"mp") | Only BE is installed/licensed | Initialize with "be" | | init raises "already initialized" | config.init called twice in one process | Guard with pystata.config.is_stata_initialized(), or use a fresh process | | SystemError: ... r(111); | Stata command error (here, variable not found) | Read the code in the message; fix the command | | Output is empty when captured | Command run with quietly=True | Drop quietly, or read results via get_return()/get_ereturn() | | Load fails on a wide dataset | Exceeds BE's 2048-variable ceiling | keep/drop columns before pdataframe_to_data | | unrecognized command for a user package | Not installed | stata.run("ssc install "), then retry |

What this skill does not do

  • It does not launch a Stata GUI window.
  • It does not call StataBE-64.exe as a subprocess or run do-files in batch

mode — everything goes through pystata's live session.

  • It does not leave permanent .do files for the user to run by hand unless

they ask for one.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.