Data Dictionary Generator
v1.0 — Auto-generate comprehensive codebooks from .dta files
Read Stata .dta files and produce a structured markdown data dictionary with variable names, types, labels, value labels, summary statistics, and missingness. Outputs a ready-to-use codebook document.
Argument: $ARGUMENTS
- Path to a .dta file or directory containing .dta files
Modes (append to argument):
summary (default) — One-page overview: variable list with types, labels, missingness
full — Comprehensive codebook: summary + value labels + summary stats + distributions for key variables
analysis — Analysis-ready: full + notes on which variables are outcomes vs controls, indices vs components
Flags:
vars:consumption,assets — Only document variables matching these patterns
output:path/to/output.md — Custom output path (default: same directory as input, named codebook_[filename].md)
format:md (default) | format:csv — Output format
Example: /data-dictionary data/for_analysis/endline_analysis.dta full
Example: /data-dictionary . vars:consumption,exp_
Example: /data-dictionary data/for_analysis/ summary
Instructions
Step 0: Locate and Load Data
- Resolve
$ARGUMENTS to find .dta file(s):
- If a file path: read that file directly
- If a directory: glob for
*.dta files in it
- If a bare name: search the current working directory and subdirectories (
data/, data/for_analysis/, output/)
- For directories with many files (>10), generate an index page + individual codebooks
- Parse mode and flags from
$ARGUMENTS. Default to summary.
Step 1: Extract Metadata
Write a temporary Python script (use uv run python or python3). Never use python -c.
import pandas as pd
import pyreadstat
df, meta = pyreadstat.read_dta("path/to/file.dta",
apply_value_formats=False)
# Available metadata:
# meta.column_names — variable names (list)
# meta.column_labels — variable labels (dict: name -> label)
# meta.variable_value_labels — value label mappings (dict: name -> {code: label})
# meta.original_variable_types — Stata storage types (dict: name -> type string)
# meta.number_columns — count of numeric columns
# meta.number_rows — row count
# meta.file_label — dataset label
# meta.notes — dataset notes
For each variable, extract:
- Name: column name
- Label: from
meta.column_labels (may be empty)
- Type: from
meta.original_variable_types (e.g., float, double, byte, int, long, str#)
- Value labels: from
meta.variable_value_labels (categorical mappings)
- N non-missing: count of non-null values
- N missing: count of null values
- Missing %: percentage missing
- Unique values: nunique
Step 2: Summary Statistics (full and analysis modes)
For numeric variables:
- Mean, SD, Min, P25, Median, P75, Max
- Flag: negative values in typically-positive variables
For string variables:
- Number of unique values
- Top 5 most frequent values with counts
- Max string length
For binary (0/1) variables:
- Proportion = 1 (with count)
For categorical variables (those with value labels):
- Frequency table: code, label, count, percentage
Step 3: Variable Classification (analysis mode only)
Attempt to classify variables by role based on naming patterns:
| Pattern |
Classification |
hhid, id, *_id |
Identifier |
treat*, arm*, t_* |
Treatment |
strat*, block*, pair* |
Stratification |
i_*, idx_*, index_* |
Index/Composite |
z_* |
Z-score |
exp_*, cons_*, income_* |
Outcome (economic) |
is_*, has_*, any_* |
Binary indicator |
mi_*, miss_* |
Missing flag |
_wins, _w, _tr |
Winsorized/trimmed |
bl_*, base_* |
Baseline |
wt_*, weight* |
Sampling weight |
Present classifications as suggestions, not assertions. Include an "Unclassified" category.
Step 4: Cross-Variable Relationships (analysis mode only)
- Index decomposition: For index variables (i_*, idx_*), identify likely component variables and report correlations
- Treatment balance: If treatment variable detected, report mean of key variables by treatment arm (first 10 numeric variables)
- Missing patterns: Identify clusters of variables with correlated missingness
Step 5: Generate Output
Output location:
- Default: same directory as input file, named
codebook_[filename]_[YYYY-MM-DD].md
- Override with
output: flag
- For directory inputs:
codebook_index_[YYYY-MM-DD].md + individual codebooks
Tell the user the full absolute path to the output file.
Output Format — Summary Mode
# Data Dictionary: [filename]
**Generated:** [YYYY-MM-DD]
**Source:** [full path]
**Dataset label:** [meta.file_label if available]
**Observations:** [N rows]
**Variables:** [N columns]
---
## Variable List
| # | Variable | Label | Type | Non-missing | Missing % | Unique |
|---|----------|-------|------|-------------|-----------|--------|
| 1 | hhid | Household ID | long | 5,000 | 0.0% | 5,000 |
| 2 | treat | Treatment arm | byte | 5,000 | 0.0% | 3 |
| ... | ... | ... | ... | ... | ... | ... |
---
## Variables Without Labels
[List any variables that have no label — these may need documentation]
---
## Notes
- [N] variables are entirely missing (0 non-missing values)
- [N] variables have >50% missing values
- [N] categorical variables have value labels defined
Output Format — Full Mode
Adds to summary:
---
## Summary Statistics — Numeric Variables
| Variable | N | Mean | SD | Min | P25 | Median | P75 | Max |
|----------|---|------|-----|-----|-----|--------|-----|-----|
| ... | ... | ... | ... | ... | ... | ... | ... | ... |
---
## Summary Statistics — Binary Variables
| Variable | Label | N | Prop = 1 | Count = 1 |
|----------|-------|---|----------|-----------|
| ... | ... | ... | ... | ... |
---
## Value Labels — Categorical Variables
### [variable_name]: [label]
| Code | Label | Count | Percent |
|------|-------|-------|---------|
| 0 | Control | 2,500 | 50.0% |
| 1 | Treatment | 2,500 | 50.0% |
[Repeat for each categorical variable with value labels]
---
## String Variables
| Variable | Label | N | Unique | Max Length | Top Values |
|----------|-------|---|--------|------------|------------|
| ... | ... | ... | ... | ... | [val1 (N), val2 (N), ...] |
---
## High Missingness Variables (>20%)
| Variable | Label | Missing % | Non-missing N |
|----------|-------|-----------|---------------|
| ... | ... | ... | ... |
Output Format — Analysis Mode
Adds to full:
---
## Variable Classification (suggested)
### Identifiers
| Variable | Label |
|----------|-------|
| hhid | Household ID |
### Treatment & Stratification
| Variable | Label | Values |
|----------|-------|--------|
| treat | Treatment arm | 0: Control, 1: Treatment |
### Outcome Indices
| Variable | Label | Mean | SD | Likely Components |
|----------|-------|------|-----|-------------------|
| i_consumption | Consumption index | 0.00 | 1.00 | exp_food, exp_nonfood, ... |
### Outcome Variables
[table]
### Control Variables / Baseline
[table]
### Missing Flags
[table]
### Unclassified
[table]
---
## Treatment Balance (first 10 numeric variables)
| Variable | Control Mean | Treatment Mean | Diff | p-value |
|----------|-------------|----------------|------|---------|
| ... | ... | ... | ... | ... |
Principles
- Comprehensive but scannable. The dictionary should work as both a reference document (ctrl+F for a variable) and a quick overview (scan the summary table).
- Metadata-first. Always use Stata's own metadata (labels, value labels, types) rather than inferring. Only infer when metadata is missing.
- Flag gaps. Unlabeled variables, undocumented value labels, and high missingness are all worth flagging — they're the most likely sources of confusion.
- Analysis mode is suggestive, not prescriptive. Variable classification is based on naming patterns and may be wrong. Present as suggestions.
- Reproducible. The output includes the source path and generation date so it's clear what version of the data was documented.
1---2name: data-dictionary3description: Auto-generate comprehensive codebooks from Stata .dta files — variable lists, summary statistics, value labels, and missingness reports4---56# Data Dictionary Generator78*v1.0 — Auto-generate comprehensive codebooks from .dta files*910Read Stata .dta files and produce a structured markdown data dictionary with variable names, types, labels, value labels, summary statistics, and missingness. Outputs a ready-to-use codebook document.1112**Argument:** `$ARGUMENTS`13- Path to a .dta file or directory containing .dta files1415**Modes** (append to argument):16- `summary` (default) — One-page overview: variable list with types, labels, missingness17- `full` — Comprehensive codebook: summary + value labels + summary stats + distributions for key variables18- `analysis` — Analysis-ready: full + notes on which variables are outcomes vs controls, indices vs components1920**Flags:**21- `vars:consumption,assets` — Only document variables matching these patterns22- `output:path/to/output.md` — Custom output path (default: same directory as input, named `codebook_[filename].md`)23- `format:md` (default) | `format:csv` — Output format2425Example: `/data-dictionary data/for_analysis/endline_analysis.dta full`26Example: `/data-dictionary . vars:consumption,exp_`27Example: `/data-dictionary data/for_analysis/ summary`2829---3031## Instructions3233### Step 0: Locate and Load Data34351. Resolve `$ARGUMENTS` to find .dta file(s):36 - If a file path: read that file directly37 - If a directory: glob for `*.dta` files in it38 - If a bare name: search the current working directory and subdirectories (`data/`, `data/for_analysis/`, `output/`)392. For directories with many files (>10), generate an index page + individual codebooks403. Parse mode and flags from `$ARGUMENTS`. Default to `summary`.4142### Step 1: Extract Metadata4344Write a temporary Python script (use `uv run python` or `python3`). Never use `python -c`.4546```python47import pandas as pd48import pyreadstat4950df, meta = pyreadstat.read_dta("path/to/file.dta",51 apply_value_formats=False)5253# Available metadata:54# meta.column_names — variable names (list)55# meta.column_labels — variable labels (dict: name -> label)56# meta.variable_value_labels — value label mappings (dict: name -> {code: label})57# meta.original_variable_types — Stata storage types (dict: name -> type string)58# meta.number_columns — count of numeric columns59# meta.number_rows — row count60# meta.file_label — dataset label61# meta.notes — dataset notes62```6364For each variable, extract:65- **Name**: column name66- **Label**: from `meta.column_labels` (may be empty)67- **Type**: from `meta.original_variable_types` (e.g., `float`, `double`, `byte`, `int`, `long`, `str#`)68- **Value labels**: from `meta.variable_value_labels` (categorical mappings)69- **N non-missing**: count of non-null values70- **N missing**: count of null values71- **Missing %**: percentage missing72- **Unique values**: nunique7374### Step 2: Summary Statistics (full and analysis modes)7576For numeric variables:77- Mean, SD, Min, P25, Median, P75, Max78- Flag: negative values in typically-positive variables7980For string variables:81- Number of unique values82- Top 5 most frequent values with counts83- Max string length8485For binary (0/1) variables:86- Proportion = 1 (with count)8788For categorical variables (those with value labels):89- Frequency table: code, label, count, percentage9091### Step 3: Variable Classification (analysis mode only)9293Attempt to classify variables by role based on naming patterns:9495| Pattern | Classification |96|---------|---------------|97| `hhid`, `id`, `*_id` | Identifier |98| `treat*`, `arm*`, `t_*` | Treatment |99| `strat*`, `block*`, `pair*` | Stratification |100| `i_*`, `idx_*`, `index_*` | Index/Composite |101| `z_*` | Z-score |102| `exp_*`, `cons_*`, `income_*` | Outcome (economic) |103| `is_*`, `has_*`, `any_*` | Binary indicator |104| `mi_*`, `miss_*` | Missing flag |105| `_wins`, `_w`, `_tr` | Winsorized/trimmed |106| `bl_*`, `base_*` | Baseline |107| `wt_*`, `weight*` | Sampling weight |108109Present classifications as suggestions, not assertions. Include an "Unclassified" category.110111### Step 4: Cross-Variable Relationships (analysis mode only)112113- **Index decomposition**: For index variables (i_*, idx_*), identify likely component variables and report correlations114- **Treatment balance**: If treatment variable detected, report mean of key variables by treatment arm (first 10 numeric variables)115- **Missing patterns**: Identify clusters of variables with correlated missingness116117### Step 5: Generate Output118119**Output location:**120- Default: same directory as input file, named `codebook_[filename]_[YYYY-MM-DD].md`121- Override with `output:` flag122- For directory inputs: `codebook_index_[YYYY-MM-DD].md` + individual codebooks123124Tell the user the full absolute path to the output file.125126---127128## Output Format — Summary Mode129130```markdown131# Data Dictionary: [filename]132133**Generated:** [YYYY-MM-DD]134**Source:** [full path]135**Dataset label:** [meta.file_label if available]136**Observations:** [N rows]137**Variables:** [N columns]138139---140141## Variable List142143| # | Variable | Label | Type | Non-missing | Missing % | Unique |144|---|----------|-------|------|-------------|-----------|--------|145| 1 | hhid | Household ID | long | 5,000 | 0.0% | 5,000 |146| 2 | treat | Treatment arm | byte | 5,000 | 0.0% | 3 |147| ... | ... | ... | ... | ... | ... | ... |148149---150151## Variables Without Labels152153[List any variables that have no label — these may need documentation]154155---156157## Notes158159- [N] variables are entirely missing (0 non-missing values)160- [N] variables have >50% missing values161- [N] categorical variables have value labels defined162```163164## Output Format — Full Mode165166Adds to summary:167168```markdown169---170171## Summary Statistics — Numeric Variables172173| Variable | N | Mean | SD | Min | P25 | Median | P75 | Max |174|----------|---|------|-----|-----|-----|--------|-----|-----|175| ... | ... | ... | ... | ... | ... | ... | ... | ... |176177---178179## Summary Statistics — Binary Variables180181| Variable | Label | N | Prop = 1 | Count = 1 |182|----------|-------|---|----------|-----------|183| ... | ... | ... | ... | ... |184185---186187## Value Labels — Categorical Variables188189### [variable_name]: [label]190191| Code | Label | Count | Percent |192|------|-------|-------|---------|193| 0 | Control | 2,500 | 50.0% |194| 1 | Treatment | 2,500 | 50.0% |195196[Repeat for each categorical variable with value labels]197198---199200## String Variables201202| Variable | Label | N | Unique | Max Length | Top Values |203|----------|-------|---|--------|------------|------------|204| ... | ... | ... | ... | ... | [val1 (N), val2 (N), ...] |205206---207208## High Missingness Variables (>20%)209210| Variable | Label | Missing % | Non-missing N |211|----------|-------|-----------|---------------|212| ... | ... | ... | ... |213```214215## Output Format — Analysis Mode216217Adds to full:218219```markdown220---221222## Variable Classification (suggested)223224### Identifiers225| Variable | Label |226|----------|-------|227| hhid | Household ID |228229### Treatment & Stratification230| Variable | Label | Values |231|----------|-------|--------|232| treat | Treatment arm | 0: Control, 1: Treatment |233234### Outcome Indices235| Variable | Label | Mean | SD | Likely Components |236|----------|-------|------|-----|-------------------|237| i_consumption | Consumption index | 0.00 | 1.00 | exp_food, exp_nonfood, ... |238239### Outcome Variables240[table]241242### Control Variables / Baseline243[table]244245### Missing Flags246[table]247248### Unclassified249[table]250251---252253## Treatment Balance (first 10 numeric variables)254255| Variable | Control Mean | Treatment Mean | Diff | p-value |256|----------|-------------|----------------|------|---------|257| ... | ... | ... | ... | ... |258```259260---261262## Principles263264- **Comprehensive but scannable.** The dictionary should work as both a reference document (ctrl+F for a variable) and a quick overview (scan the summary table).265- **Metadata-first.** Always use Stata's own metadata (labels, value labels, types) rather than inferring. Only infer when metadata is missing.266- **Flag gaps.** Unlabeled variables, undocumented value labels, and high missingness are all worth flagging — they're the most likely sources of confusion.267- **Analysis mode is suggestive, not prescriptive.** Variable classification is based on naming patterns and may be wrong. Present as suggestions.268- **Reproducible.** The output includes the source path and generation date so it's clear what version of the data was documented.