Full-empirical-analysis-skill-Stata
Full-empirical-analysis-skill-Stata について
応用経済学の研究者向けに、経済学、疫学、因果機械学習を扱う8段階の実証分析を案内するStataスキルです。検証可能な再現性のある .do ファイルと、論文向けの表や図の作成を重視します。
主な機能
- 018段階の実証分析パイプライン
- 02経済学・疫学・因果MLのモード
- 03再現可能なStata .doファイル
- 04診断とロバスト性検定
- 05表と図のエクスポート
活用シーン
- 01DID、IV、RD、イベントスタディの分析
- 02疫学・公衆衛生の分析
- 03DMLや因果フォレストの推定
- 04論文用の表や図の作成
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ brycewang-stanford/ auto-empirical-research-skills --skill full-empirical-analysis-skill-stataインストール後、Claude Code で/full-empirical-analysis-skill-stataを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
README.mdreferences/04-statistical-tests.md08-tables-plots.md01-data-cleaning.md02-data-transformation.md07-further-analysis.md06-robustness.md03-descriptive-stats.md05-modeling.md詳細
完全な実証分析 — 従来型の Stata ワークフロー
このスキルは、応用経済学者があらゆる実証論文で実行する、標準的な8ステップのパイプラインです。従来型の Stata エコシステム(ネイティブの Stata と、デファクトスタンダードとなった20以上のコミュニティ製コマンド(reghdfe、ivreg2、csdid、did_imputation、eventstudyinteract、sdid、rdrobust、rddensity、synth、synth_runner、psmatch2、teffects、ebalance、coefplot、esttab、outreg2、boottest、ritest、rwolf、bacondecomp、honestdid、binscatter))を前提に記述されています。
関連スキル:ユーザーが同じパイプラインを Python で実行したい場合は、00-StatsPAI_skill(エージェントネイティブ DSL)または 00.1-Full-empirical-analysis-skill(明示的な Python スタック)を案内してください。このスキルは Stata 版です。各ステップで .do ファイルが生成されるので、学術誌の再現性確認担当者や、Stata から離れようとしない共著者に渡せます。
基本方針
- Python に翻訳したものではなく、Stata の慣用的な書き方を使います。
reghdfeを使い、「reghdfe の statsmodels 相当」は使いません。esttabを使い、「Stata 版 stargazer」は使いません。 - 再現可能な .do ファイルを作成します。 以下の各コードブロックは、
use data.dta, clearの後に実行できます。Jupyter もノートブックも使わず、do ファイルとログファイルだけを使います。 - 回帰だけでなく、パイプライン全体を扱います。 Stata ユーザーは従来、ステップ5(モデリング)に過剰に注力し、ステップ1〜4および6〜8を軽視しがちです。このスキルでは、これらも同等に重視します。
- 豊富な出力を作成します。 各ステップで、少なくとも1つの表(
.tex/.rtf)または図(.pdf/.png)を生成します。Stata の Results ウィンドウに係数を表示して終わり、ということはありません。 - 段階的に詳細を示します。
SKILL.mdでは各ステップの標準コマンドを示し、references/には手法別の詳しい情報(多数の検定、推定量ごとの診断、グラフの作成方法)を記載しています。
SkillOpt 形式の実行ゲート
この長いプレイブックはシードスキルとして使い、すべてを網羅的に適用するスクリプトとして扱わないでください。SkillOpt の規律として、各ローカル .do ファイルの変更は候補パッチとみなし、再利用可能な定型コードにする前に、選択チェックを通過し、ホールドアウトチェックにも耐える必要があります。.do ファイルを作成または修正する前に、ユーザーの依頼をタスク固有の best_skill カードにまとめます。
best_skill: <mode + design + artifact target>
train_signal: <current failure, user goal, or missing evidence>
selection_split: <focal dataset/spec/output used to judge the candidate>
heldout_gate: <checks the patch must pass beyond the focal example>
accepted_patterns: <rules to reuse after validation>
rejected_patterns: <failed shortcuts not to retry without new evidence>
patch_scope: <one estimator/sample/export/robustness change>
reject_if: <conditions that force rollback to the last passing spec>
- ルーティングカード:モード(
econ、epi、ml-causalのいずれか)、推定対象、識別デザイン、主要なアウトカム/処置、Stata コマンドファミリー、必要な成果物を記録します。 - 変更範囲の限定:一度に変更する判断事項は1つにします(サンプル規則、推定コマンド、固定効果、クラスタリング、出力形式、頑健性チェックなど)。検証に合格できる最小限のパッチを優先します。
- 選択用分割の規律:ユーザーが直面している問題または依頼された成果物を選択用分割として扱います。別のアウトカム、サンプル期間、推定コマンドファミリー、出力先のいずれかを少なくとも1つ、ホールドアウトゲート用に確保します。
- ホールドアウトゲート:コードの実行前にチェック項目を定義します。
isid/重複の状態、マージのアサーション、処置のサポート、欠損率のしきい値、期待される表/図ファイル、そして変更によって壊してはならない主要対象以外の頑健性/仕様を含めます。 - 却下バッファー:候補仕様がゲートを通過しなかった場合は、失敗内容、
.doの差分、ゲートの出力をanalysis_log.mdまたは Stata のログに記録し、最後に合格した仕様に戻します。同じ未検証のパターンを再試行してはいけません。 - 低速/メタ更新:タスクの最後に、実行の経過から
accepted_patternsとrejected_patternsを書き留めます。1回の実行に合格しただけで、標準の.doテンプレートを拡張してはいけません。 - 検証後にのみ昇格:一度限りの修正を再利用可能な
.doの定型コードにするのは、現在のデータで合格し、さらに別のアウトカム/サンプル/仕様の少なくとも1つでも合格した後に限ります。
3 つの分野モード(デフォルト=AER 経済学、代替=疫学と ML 因果推論)
上記のデフォルトのプレイブックは、AER スタイルの応用計量経済学、つまり AEA の慣例に沿ったものです。推定方程式を明記し、識別仮定を示し、設計の比較検討を行い、徹底したロバスト性検証を実施します。このスキルには、ほかの主要な因果推論の流儀に対応する 2 つの並行サブパイプラインも含まれています。どちらも同じ Steps 1–4(クリーニング/構築/Table 1/診断)と Step 8(表/図)を再利用し、コマンドを切り替えるのは Step 5(推定量)と Steps 6/7 のみです。
| モード | 読者の慣例 | Step 5 の推定量スタック | 報告スタック | 移動先 |
|---|---|---|---|---|
| デフォルト — 応用経済学(AER / QJE / AEJ) | 「方程式+識別仮定+設計の比較検討を示す。統制変数を明示し、標準誤差をクラスター化する」 | DID / IV / RD / SCM / マッチング / reghdfe HDFE | AER のハウススタイルによる複数列の esttab / outreg2 / coefplot + 8 セクションの論文構成 | Steps 1 → 8(以下のプレイブック全体) |
| モード A — 疫学/公衆衛生 | 「STROBE / TRIPOD-AI、ターゲットトライアルのプロトコル、二重ロバストな推定対象、絶対リスクと相対リスク、KM 生存分析」 | ターゲットトライアル・エミュレーション · IPTW(teffects ipw) · IPWRA / AIPW(teffects ipwra / teffects aipw) · g-formula(gformula) · TMLE(eltmle) · メンデルランダム化(mrrobust IVW / mregger / mrpresso) · KM/Cox/AFT(sts/stcox/streg/strmst2) | 同じ esttab + リスク差/ハザード比/E-value の行 | §A. 疫学パイプライン |
| モード B — ML 因果推論 | 「DML / メタラーナー / 因果フォレスト / DR-Learner、CATE 分布、ポリシー価値」 | DML(ddml / pdslasso) · S/T/X/R/DR-Learner(ddml interactive) · GRF 因果フォレスト(crforest / cforest) · BART / BCF(python_user 経由の外部 Python) · 行列補完(外部) | esttab による ML の比較検討 + crforest の CATE プロット + ポリシー価値の表 | §B. ML 因果推論パイプライン |
デフォルト以外のモードの呼び出し方(Claude / エージェントがユーザーの表現から判定します):
| ユーザーの表現... | スキルが切り替えるモード |
|---|---|
| 「DID / IV / RD / イベントスタディを実行」「AER テーブル」「応用ミクロ」 | デフォルト(AER 経済学)— Steps 1 → 8 |
| 「ターゲットトライアル・エミュレーション」「g-formula」「IPTW」「TMLE」「メンデルランダム化」「STROBE / TRIPOD」「公共健康 / 流行病学」「疫学パイプライン」「RWE 研究」「コホート研究」「症例対照研究」 | モード A(疫学)— §A |
| 「DML」「ダブルマシンラーニング」「ddml」「因果フォレスト」「crforest」「メタラーナー」「CATE」「ポリシー学習」「ML 因果推論」「因果机器学习」 | モード B(ML 因果推論)— §B |
| 「組み合わせ」(例:「DID を推定してから、異質性に対して ML CATE を推定」) | デフォルト+モード B の順に実行 — すべての推定量の結果を eststo で保存し、比較検討用の列としてすべてを 1 つの esttab にまとめます |
3 つのモードでは、Steps 1–4 のクリーニング/Table 1/診断の枠組み、Step 8 のエクスポートスタック、DAG を最初に用いる識別ロジックが共通です。モードを切り替えると変わるのは、Step 5 で使用するコマンド群のみです。記述統計/Table 1/バランスチェックだけが必要な場合は、Step 3 の AER の tabstat / balancetable / asdoc 呼び出しを、3 つのモードすべてで同じように使用できます。
モード B に関する Stata 固有の注意点:Stata の公式 ML 因果推論機能は、Python/R より限定的です。Dragonnet / TARNet / CEVAE / cfcausal / 公平性監査には、Stata 18 の
python:/python scriptブロックを使って Python を呼び出す(または姉妹ファイルの.pyをシェルから実行する)方法を使用し、結果をframeまたはimport delimitedで読み戻してください。このスキルでは、ネイティブの Stata コマンド(ddml、pdslasso、crforest)がある場合はそれを優先し、§B では Python の呼び出し箇所を明示しています。
デフォルトの出力仕様 — 経済学の実証論文
このスキルでは、デフォルトで応用経済学の論文の慣例を採用します。ユーザーが単一の点推定値を明示的に求めない限り、すべての .do ファイルの実行で、以下の出版可能な出力一式を生成します。これは Step 8 の要件であり、必須です。任意ではありません。
必須の表(常に作成)
| # | 表 | Stata のソース | 保存先 |
|---|---|---|---|
| T1 | 要約統計量とバランス(処置群 vs 対照群、SMD / p 値付き) | balancetable + asdoc sum(Step 3) | tables/table1_balance.{tex,rtf,xlsx,docx} |
| T2 ★ | 主な結果 — 複数列の回帰 M1→M6(統制変数 + FE を段階的に追加) | eststo で 6 つの仕様 → esttab(Step 5–6) | tables/table2_main.{tex,rtf,xlsx,docx} |
| T3 | メカニズム / アウトカムの階層 — 同じ処置について、3 つ以上のアウトカムを横並びで表示 | アウトカムをループして eststo: reghdfe → esttab(Step 7) | tables/table3_mechanism.{tex,rtf,xlsx,docx} |
| T4 | 異質性 — サブグループ × 主な係数(性別、年齢、地域など) | サブグループの eststo + suest Wald → esttab(Step 7) | tables/table4_heterogeneity.{tex,rtf,xlsx,docx} |
| T5 | 頑健性の一括検証 — 代替 SE / クラスター / サンプル / プラセボを1 つの表にまとめる | eststo × 各種バリエーション → esttab(Step 6) | tables/table5_robustness.{tex,rtf,xlsx,docx} |
★ 表 2 は、すべての経済学論文の中心となる表です。 生の相関(M1)から完全に指定された設計(M6:2-way FE + 交互作用 FE + クラスターロバスト SE)までを読者に示す、複数列の回帰表です。単一列にまとめてはいけません。主要な係数だけを報告してはいけません。この段階的な推移こそが信頼性の論拠です。M1→M6 が単調かつ安定していれば、設計によって因果効果を識別できている可能性があります。FE の追加で結果が消えるなら、それ自体が結果です。
標準の 6 列(順序どおり):
- M1 生の二変量回帰(
reg y treat)- M2 + 人口統計学的変数(
+ age + edu)- M3 + セクターの統制変数(
+ tenure / firm_size)- M4 + 単位 FE(
reghdfe ..., absorb(unit))- M5 + 2-way FE(
absorb(unit year))- M6 + 交互作用 FE(
absorb(unit year i.industry#i.year))、vce(cluster unit)を指定
必須の図(常に作成)
| # | 図 | Stata のソース | 保存先 |
|---|---|---|---|
| F1 | トレンド / 動機付け — 処置群と対照群の時系列推移、政策実施時点の線付き | collapse (mean) y, by(year treat) → twoway line(Step 3) | figures/fig1_trend.pdf(+ .png) |
| F2 | 95% CI 付きイベントスタディ係数、基準期間は –1 | eventstudyinteract / csdid / coefplot, keep(*.rel)(Step 5) | figures/fig2_event_study.pdf |
| F3 | 仕様 M1→M6 の係数プロット | coefplot m1 m2 m3 m4 m5 m6, keep(treat) vertical(Step 8) | figures/fig3_coefplot.pdf |
| F4 | 頑健性 / 感度曲線 — bacondecomp プロット、honestdid プロット、またはクラスター比較フォレストプロット | シナリオごとに指定(Step 6) | figures/fig4_sensitivity.pdf |
出力ファイルの構成(デフォルト)
project/
├── tables/ table1_balance.{tex,rtf,xlsx,docx} table2_main.{tex,rtf,xlsx,docx}
│ table3_mechanism.{tex,rtf,xlsx,docx} table4_heterogeneity.{tex,rtf,xlsx,docx}
│ table5_robustness.{tex,rtf,xlsx,docx}
└── figures/ fig1_trend.{pdf,png} fig2_event_study.{pdf,png}
fig3_coefplot.{pdf,png} fig4_sensitivity.{pdf,png}
すべての表を .tex(LaTeX booktabs)、.rtf(Word)、.xlsx(Excel)、.docx(Word OOXML)で出力します。すべての図を .pdf(LaTeX 用のベクター形式)および .png(スライド / Web 用、解像度 300 dpi 以上)で出力します。
例外とする場合
- 単一の簡易推定 — 関連するセルだけを作成します。ただし、標準の納品物は上記一式であることを伝え、実行するかどうかを確認します。
- 設計上、図を作成できない場合(横断面データ → イベントスタディなし)— 理由を説明する
displayメモを出力してスキップします。黙って省略してはいけません。 - 処置単位が N=1(
synth)の場合 — F1/F2 を、synth_runnerによる SCM の軌跡 + プラセボ分布に置き換えます。T1–T5 は引き続き適用されます。
必須パッケージ
* Run once on a fresh Stata install:
ssc install reghdfe, replace
ssc install ftools, replace // dependency of reghdfe / ivreg2
ssc install ivreg2, replace
ssc install ranktest, replace // dependency of ivreg2
ssc install ivreghdfe, replace // ivreg2 × reghdfe: high-dim FE IV
ssc install ppmlhdfe, replace // Poisson with HD FE
ssc install csdid, replace // Callaway–Sant'Anna (2021)
ssc install drdid, replace // dependency of csdid
ssc install did_imputation, replace // Borusyak–Jaravel–Spiess (2024)
ssc install eventstudyinteract, replace // Sun & Abraham (2021)
ssc install sdid, replace // Synthetic DID (Arkhangelsky et al. 2021)
ssc install did_multiplegt_dyn, replace // de Chaisemartin & D'Haultfœuille
ssc install bacondecomp, replace // Goodman-Bacon (2021)
ssc install honestdid, replace // Rambachan–Roth (2023) PT sensitivity
ssc install rdrobust, replace // Calonico–Cattaneo–Titiunik RD
ssc install rddensity, replace // McCrary / Cattaneo et al. density test
ssc install synth, replace // Abadie–Diamond–Hainmueller SCM
ssc install synth_runner, replace // SCM with placebos + inference
ssc install psmatch2, replace // propensity-score matching
ssc install ebalance, replace // entropy balancing
ssc install coefplot, replace
ssc install estout, replace // provides estout / esttab / eststo
ssc install outreg2, replace
ssc install asdoc, replace // one-click Word/Excel tables
ssc install binscatter, replace
ssc install balancetable, replace
ssc install winsor2, replace
ssc install xtable, replace // better xtreg output tables
ssc install boottest, replace // wild cluster bootstrap (Roodman et al.)
ssc install ritest, replace // randomization inference
ssc install rwolf, replace // Romano–Wolf multiple-testing
ssc install moremata, replace // Mata extensions (dep for several)
ssc install mdesc, replace // missing data description
ssc install missings, replace // missings dropvars, report
ssc install unique, replace // unique IDs in panel
ssc install schemepack, replace // modern publication themes
8つのステップ — 標準パイプライン(AER論文のセクションに対応)
┌──────────────────────────────────────────────────────────────────────┐
│ Step −1 Pre-Analysis Plan (PAP) power/sampsi/clustersampsi/MDE │
│ Step 0 Sample log + data contract sample_log/assert/xtdescribe/JSON │
│ Step 1 Data import & cleaning use/import/destring/misstable/merge│
│ Step 2 Variable construction gen/egen/winsor2/xtile/xtset/L.F.D.│
│ Step 2.5 Empirical strategy equation × ID assumption + pre-reg │
│ Step 3 Descriptive statistics tabstat/balancetable/asdoc/pwcorr │
│ Step 3.5 Identification graphics event-study/1st-stage/McCrary/love │
│ Step 4 Diagnostic tests sktest/hettest/xtserial/vif/dfuller│
│ Step 5 Baseline modeling reghdfe/ivreg2/csdid/rdrobust/synth│
│ Step 6 Robustness battery bacondecomp/honestdid/rwolf/boottest│
│ Step 7 Further analysis triple-diff/subgroup/medsem/margins│
│ Step 8 Tables & figures esttab/outreg2/coefplot/rdplot │
└──────────────────────────────────────────────────────────────────────┘
8つのステップは、応用ミクロ経済学のAER/QJE/AEJ論文の標準的なセクションに対応しています。各ステップは論文の1セクションに相当し、論文にそのまま使える成果物をディスクに出力します。
Paper section Step Stata moves
─────────────────────────── ───── ────────────────────────────────────────────────
Pre-Analysis Plan −1 power/sampsi + freeze protocol.do to disk
§1. Data 0 sample_log + 5-check data contract → JSON
§1. Data 1 use/import/destring/misstable/merge assert/xtset
§1. Data 2 gen/egen/winsor2/xtile/L./F./D./CPI deflation
§1.1 Descriptives (Table 1) 3 tabstat · balancetable · asdoc · pwcorr · twoway
§2. Empirical Strategy 2.5 write equation + ID assumption → strategy.do
§3. Identification graphics 3.5 event-study · 1st-stage F · McCrary · love · SCM
§3.5 Diagnostics 4 swilk · hettest · xtserial · vif · dfuller · hausman
§4. Main Results (Table 2) 5 M1→M6 progressive controls + FE (eststo + esttab)
§5. Heterogeneity (Table 3) 7 margins/marginsplot · subgroup · medsem
§6. Mechanisms / Channels 7 medsem/khb · outcome ladder · DDD interactions
§7. Robustness gauntlet 6 bacondecomp · honestdid · psacalc · boottest · ritest · rwolf
§8. Replication package 8 esttab + outreg2 + coefplot + reproducibility stamp
以下は各ステップで使う標準コマンドです。すべての例は、1つの一貫したストーリーに基づいています。具体的には、training(処置)がlog_wage(アウトカム)に与える影響を分析する労働経済学のパネルデータで、共変量はage、edu、tenure、パネルキーはworker_id/firm_id/yearです。変数名とパラメーター値は例示用です。ユーザーのデータセットに応じて実際のものに置き換えてください。規範となるのはコマンド名とオプションの形式のみです。
ステップに多くのバリエーションがある場合(例:段階的DIDには5種類の推定量、異分散性には4種類の古典的検定があります)、SKILL.mdでは最初に使う手法を示し、その他の手法については
references/NN-<topic>.mdにリンクしています。ユーザーのケースが標準的なケースに当てはまらない場合は、リファレンスファイルを読んでください。
論文で使える図表の一覧(各セクションで作成するもの)
現代のAER論文では、5~7点の図と、主要な表3~5点に加えて、付録の頑健性検証表を掲載します。以下の各ステップでは、少なくとも1つの番号付き成果物をディスクに出力します。既定のファイル名では、.tex/.rtfの両形式でエクスポートすることを想定しています(エージェントは、共著者がWordで編集できるように、またビルドシステムでLaTeXを使用できるように、両方を作成してください)。
| § | 成果物 | Stataの基本コマンド | ファイル名 |
|---|---|---|---|
| §1 | 図1:生データのトレンド/処置の導入状況 | collapse + twoway line · 段階的な導入状況にはheatplot | figures/fig1_trend.{pdf,png} |
| §1 | 表1:要約統計量(全体/処置群/対照群 + Δ + SMD) | balancetable · asdoc sum, by() · tabstat | tables/table1_balance.{tex,rtf,xlsx,docx} |
| §3 | 図2:識別の図(イベントスタディ/第一段階/McCrary/RD散布図/SCMの推移) | eventstudyinteract/csdidの後にcoefplot · binscatter · rdplot · rddensity, plot · synth | figures/fig2_event_study.{pdf,png} |
| §4 | 表2:主要結果 — 段階的に統制変数を追加したM1→M6 | eststoで6つの仕様を推定 → esttab | tables/table2_main.{tex,rtf,xlsx,docx} |
| §4 | 表2-bis:識別設計の競合比較(OLS/IV/DID/マッチング) | 複数の推定結果をeststoで保存 + esttab | tables/table2b_designs.{tex,rtf,xlsx,docx} |
| §4 | 図3:各仕様の係数プロット | coefplot m1 m2 m3 m4 m5 m6, keep(treat) | figures/fig3_coefplot.{pdf,png} |
| §5 | 表3:サブグループ別の異質性 | スライスごとにeststo + esttab + suestのWald検定 | tables/table3_heterogeneity.{tex,rtf,xlsx,docx} |
| §5 | 図4:用量反応/四分位別のマージン | xtile + margins + marginsplot | figures/fig4_dose.{pdf,png} |
| §6 | 表4:メカニズム/アウトカムの段階的分析 | アウトカムを順にループしてeststo: reghdfe → esttab | tables/table4_mechanism.{tex,rtf,xlsx,docx} |
| §7 | 表A1:頑健性検証の一覧(各検証を1列に表示) | バリエーションごとにeststo → esttab | tables/tableA1_robustness.{tex,rtf,xlsx,docx} |
| §7 | 図5:仕様曲線 — すべての仕様における係数 + 95%信頼区間 | 手動で仕様をループ + twoway rcap | figures/fig5_spec_curve.{pdf,png} |
| §7 | 図6:感度分析(HonestDiD/Oster/E-value) | honestdid, coefplot · psacalc plot · evalueの表 | figures/fig6_sensitivity.{pdf,png} |
| §8 | 再現用バンドル:すべての表を1つの文書にまとめる | esttab ..., appendで1つの.tex/.rtfに出力 · texdoc | replication/paper_tables.{tex,rtf,xlsx,docx} |
上記のすべてのStata推定量は、結果を
eststoで保存し、そのままesttab/coefplot/outreg2に渡せます。LaTeXを手作業で作成したり、outsheet/putexcelの行列からWord文書を生成したりしないでください。esttabとoutreg2は、ブックタブ形式の罫線、AERスタイルの有意性を示す星印、適切な標準誤差ラベルを自動的に適用します。エクスポート方法の詳しいレシピ(LaTeX/Word/Markdown形式、texdoc、frmttable)については、references/08-tables-plots.mdを参照してください。
エクスポートのレシピ — LaTeX / Word / RTF をまとめて出力
Stata のエクスポート機能は、Python の StatsPAI よりも分断されています。対象範囲に応じて、次の 3 つの階層から選びます。
| 階層 | 使用する場面 | API | 主なオプション |
|---|---|---|---|
| 1. 単一の複数列テーブル | 列を段階的に追加する Table 2 / Table 3 / Table A1 を 1 つエクスポートする場合 | .tex / .rtf:booktabs と esttab.xlsx / .docx:outreg2(esttab の Office ネイティブエクスポートはデータを出力するだけで、論文向けの書式設定には対応していません。outreg2 は、罫線、位置のそろったアスタリスク、AER スタイルのレイアウトを備えた、適切に書式設定された Word / Excel ファイルを作成します) | tex / rtf には esttab:keep()、drop()、mtitles()、stats(N r2 r2_a, labels(...))、star(* 0.10 ** 0.05 *** 0.01)、label、booktabs、addnotes()。xlsx / docx には outreg2:固定効果の指標には label dec(3)、addtext() を使用し、最初の列では replace、後続の列では append を指定します。必ず 4 つすべての形式を出力します。tex / rtf には foreach ext in tex rtf ループ内で esttab を使用し、xlsx / docx には別の foreach ext in xlsx docx ループ内で outreg2 を使用します。 |
| 2. 複数パネルの論文形式(Table 2 + 3 + A1 + A2 を 1 つのファイルにまとめる) | 論文の表のブロックを作成する場合 — メイン、異質性、頑健性、プラセボの各分析を 1 つの文書にまとめます | 最初のパネルには esttab ... using "paper.tex", replace を使用し、次の各パネルには esttab ... using "paper.tex", append を使用します。本文を含む LaTeX ファイル全体を作成するには texdoc init "paper.tex" を使用します。.rtf / .xlsx / .docx の一式についても同様に繰り返します。 | 最初のパネル:replace、後続のパネル:append。見出しを付ける場合は texdoc で囲みます |
3. セッション全体の一式(Stata 17 以降の collect 相当) | 要約統計、バランス、多数の回帰表、見出し、本文を1 つのファイルにまとめる再現性付録を作成する場合 | collect create papercollect get summary, ...collect get est ...collect layout ...collect export "paper.xlsx"(.docx / .html / .tex / .md も出力可能) | Stata 17 以降のみ。古いバージョンの Stata では texdoc / markdoc を使用します |
学術誌の書式 — 適切な star の水準と SE ラベルを選びます。 AEA の慣例は * 0.10 ** 0.05 *** 0.01 と SE ラベル「Standard errors in parentheses」です。QJE / Econometrica / RES の形式は、アスタリスク / 注記 / フォントのみが異なります。do ファイルの冒頭で esttab のラッパーを一度定義します。
* Top of master.do — journal house-style wrapper
local AER_STAR "* 0.10 ** 0.05 *** 0.01"
local AER_NOTES "Cluster-robust standard errors in parentheses. * p<0.10, ** p<0.05, *** p<0.01."
local AER_STATS stats(N r2_a, labels("N" "Adj. R²"))
* LaTeX + RTF via esttab (booktabs for tex)
* esttab m1 m2 m3 using "tables/table2.tex", replace ///
* se star(`AER_STAR') label booktabs `AER_STATS' addnotes(`AER_NOTES')
* esttab m1 m2 m3 using "tables/table2.rtf", replace ///
* se star(`AER_STAR') label `AER_STATS' addnotes(`AER_NOTES')
* Excel + Word via outreg2 (publication-grade Office formatting)
* First column: replace; subsequent: append
* outreg2 using "tables/table2.xlsx", replace label dec(3) ///
* keep(training age edu tenure) addtext(Worker FE, Yes, Year FE, Yes)
* outreg2 using "tables/table2.xlsx", append label dec(3) ///
* keep(training age edu tenure region) addtext(Worker FE, Yes, Year FE, Yes, Region, Yes)
複数形式でのエクスポートのパターン — esttab で .tex と .rtf を出力し、続いて outreg2 で .xlsx と .docx を出力します。esttab ... using "... .xlsx" や esttab ... using "... .docx" は使用しないでください。esttab の Office ネイティブエクスポートは、論文向けの書式設定ではなく、生データを出力するだけです。
* LaTeX + RTF — use esttab (booktabs for tex, rich text for rtf)
foreach ext in tex rtf {
esttab m1 m2 m3 using "tables/table2_main.`ext'", ///
replace se star(* 0.10 ** 0.05 *** 0.01) ///
label booktabs mtitles("(1)" "(2)" "(3)") ///
stats(N r2_a, labels("N" "Adj. R²")) ///
addnotes("Cluster-robust SE in parentheses. * p<0.10, ** p<0.05, *** p<0.01.")
}
* Excel + Word — use outreg2 (proper Office table formatting, aligned stars, borders)
* First model: replace
eststo m1: qui reghdfe log_wage training age edu tenure, absorb(worker_id year) vce(cluster worker_id)
outreg2 using "tables/table2_main.xlsx", replace label dec(3) ///
keep(training age edu tenure) ///
addtext(Worker FE, Yes, Year FE, Yes)
* Subsequent models: append
eststo m2: qui reghdfe log_wage training age edu tenure region, absorb(worker_id year) vce(cluster worker_id)
outreg2 using "tables/table2_main.xlsx", append label dec(3) ///
keep(training age edu tenure region) ///
addtext(Worker FE, Yes, Year FE, Yes, Region, Yes)
* docx follows the same pattern but with the .doc extension
outreg2 using "tables/table2_main.doc", replace label dec(3) ///
keep(training age edu tenure) ///
addtext(Worker FE, Yes, Year FE, Yes)
eststo m2
outreg2 using "tables/table2_main.doc", append label dec(3) ///
keep(training age edu tenure region) ///
addtext(Worker FE, Yes, Year FE, Yes, Region, Yes)
図は必ず .pdf と .png の両方に 300 dpi 以上でエクスポートします(LaTeX にはベクター形式、スライド / Web / Word への埋め込みにはラスター形式を使用します)。
graph export "figures/fig1_trend.pdf", replace
graph export "figures/fig1_trend.png", replace width(2400) height(1800)
collect / texdoc / markdoc のレシピ(Stata 17 以降での複数パネルの論文一式、および本文と表を含む PDF / Word の生成)については、references/08-tables-plots.md を参照してください。
ステップ −1 — 分析計画(データを扱う前;AEA RCT Registry 形式)
データに触れる前に、(a)母集団、(b)研究デザイン、(c)計画したサンプルサイズと α=0.05、β=0.20 に基づく**最小検出可能効果(MDE)**を記録します。結果を protocol.do として保存すれば、データを見る前に、事後ではなく事前に検出力を確保したデザインであることを査読者が確認できます。
* Two-sample MDE (continuous outcome, Cohen's d framing)
power twomeans 0, diff(0.2) sd(1) power(0.80) alpha(0.05)
* → required n per arm
* Cluster-randomized RCT — solve for n_clusters given ICC
power twomeans 0, diff(0.2) sd(1) power(0.80) k1(50) rho(0.05) cluster
* → required clusters per arm under ICC=0.05, cluster size 50
* DID power (Frison–Pocock / Bloom 1995): use -sampsi- + -clustersampsi-
* (no native `power did`; for staggered DID see references/05-modeling.md §5.4)
sampsi 0 0.15, sd(1.0) alpha(0.05) power(0.80) n1(.) n2(.)
* RD power — McCrary-style: solve via Monte Carlo with -simulate-
* (see references/05-modeling.md §5.5 RD power template)
* Persist the protocol — referee will ask whether design was powered ex ante
file open f using "protocol.do", write replace
file write f "* Pre-analysis plan — frozen `c(current_date)' `c(current_time)'" _n
file write f "* Population: manufacturing workers 2010-2020" _n
file write f "* Treatment: training (binary)" _n
file write f "* Outcome: log_wage" _n
file write f "* Design: staggered DID, csdid (Callaway-Sant'Anna 2021)" _n
file write f "* MDE: 0.05 log points at 80% power, α=0.05" _n
file write f "* N planned: ~12,000 worker-years" _n
file close f
ステップ 1 を実行する前に、この .do ファイルをバージョン管理に保存します。AEA RCT Registry / OSF の事前登録ツールでは、これを分析計画の資料として提出できます。
ステップ 0 — サンプル構築ログと 5 項目のデータ契約
AER の §1「Data」セクションには 3 つの役割があります。(a)データソースを説明すること、(b)すべてのサンプル制限(「脚注 4」のサンプルログ)を記録すること、(c)パネル構造を固定することです。Stata のユーザーは通常、カウントログを残さずに 1 つの do ファイル内で keep / drop コマンドを連ねるため、回答書の作成時に分析サンプルを再構成できなくなります。データ契約はその解決策です。
0.1 サンプル構築ログ(脚注 4)
use "raw.dta", clear
matrix sample_log = J(0, 2, .)
local row 0
local n0 = _N
local ++row
matrix sample_log = (nullmat(sample_log) \ `row', `n0')
display "Step 0. raw: N = " %12.0fc `n0'
drop if missing(wage)
local n1 = _N
local ++row
matrix sample_log = (nullmat(sample_log) \ `row', `n1')
display "Step 1. drop missing wage: N = " %12.0fc `n1' " (Δ " %10.0fc `n0' - `n1' ")"
drop if !inrange(age, 18, 65)
local n2 = _N
local ++row
matrix sample_log = (nullmat(sample_log) \ `row', `n2')
display "Step 2. drop age outside 18-65: N = " %12.0fc `n2' " (Δ " %10.0fc `n1' - `n2' ")"
keep if inlist(industry, "manuf", "construction", "transport")
local n3 = _N
local ++row
matrix sample_log = (nullmat(sample_log) \ `row', `n3')
display "Step 3. keep target industries: N = " %12.0fc `n3' " (Δ " %10.0fc `n2' - `n3' ")"
* Persist to JSON (for paste into footnote 4)
file open f using "artifacts/sample_construction.json", write replace
file write f "{" _n
file write f `" "step_0_raw": `=sample_log[1,2]',"' _n
file write f `" "step_1_wage": `=sample_log[2,2]',"' _n
file write f `" "step_2_age": `=sample_log[3,2]',"' _n
file write f `" "step_3_indust": `=sample_log[4,2]'"' _n
file write f "}" _n
file close f
display の行をそのまま論文の脚注 4 に貼り付けます。
0.2 5項目のデータ契約(Go/No-Go ゲート)
* (1) Shape
display "Check 1. n_obs = " _N
* (2) Dtypes on key vars — assert types are numeric where required
foreach v in wage training worker_id year age edu tenure {
capture confirm numeric variable `v'
if _rc {
display as error "Check 2 FAILED: `v' is not numeric — fix before any panel command"
exit 198
}
}
display "Check 2. dtypes OK on all key vars"
* (3) Missingness pattern on key vars
mdesc wage training worker_id year age edu tenure // ssc install mdesc
foreach v in wage training worker_id year {
qui count if missing(`v')
if r(N) > 0 {
display as error "Check 3 FAILED: `v' has " r(N) " missing — fix before estimation"
exit 198
}
}
* (4) Duplicate (id, time) — fatal for panel methods
duplicates report worker_id year
duplicates tag worker_id year, gen(dup)
qui count if dup > 0
if r(N) > 0 {
display as error "Check 4 FAILED: " r(N) " duplicate (worker_id, year) rows"
exit 198
}
drop dup
* (5) Panel balance
xtset worker_id year
xtdescribe
qui xtdes
local n_balanced = r(N)
display "Check 5. panel n=" _N " (balanced cells if `n_balanced' equals expected unit×period)"
* MCAR sniff test (Rubin) — if missing(y) is associated with covariates,
* listwise deletion biases the estimate. Use `mi` / IPW instead.
gen byte miss_y = missing(wage)
foreach cov in age edu tenure {
qui ttest `cov', by(miss_y)
if r(p) < 0.05 {
display as error "WARNING: y-missingness associates with `cov' (p=" %5.3f r(p) ")."
display as error " -> NOT MCAR, use -mi impute- or IPW, NOT listwise drop."
}
}
drop miss_y
* Persist contract
file open f using "artifacts/data_contract.json", write replace
file write f "{" _n
file write f `" "n_obs": `=_N',"' _n
file write f `" "panel": "worker_id × year","' _n
file write f `" "treatment": "training","' _n
file write f `" "outcome": "log_wage""' _n
file write f "}" _n
file close f
アサーションが1つでも発生した場合は、停止して修正してください。Stata の推定コマンドは NaN の行を通知なく除外します。これは、回答書で「サンプルサイズが不可解に縮小する」バグの最も一般的な原因です。
ステップ 1 — データのインポートとクリーニング
詳しいパターンについては、references/01-data-cleaning.md を参照してください。Excel/CSV/SAS/SPSS の読み込み、数値に見える文字列への destring、misstable のパターン、duplicates によるタグ付け、assert(match using) を使った merge、xtset のバランスチェック、期間/ギャップ、ラベルを扱います。
* 1a. Load + first look
use "raw.dta", clear
describe, short
summarize
misstable summarize
mdesc // missing-data report
* 1b. Dtypes — destring strings-that-should-be-numeric
destring year wage, replace force // force: convert non-numeric to .
gen hire_date = date(hire_date_str, "YMD"); format hire_date %td
* 1c. Missing values — decide PER VARIABLE
local key_vars "wage training worker_id year"
foreach v of local key_vars {
drop if missing(`v')
}
sum tenure, detail
replace tenure = r(p50) if missing(tenure) // median-impute
gen byte tenure_miss = missing(tenure) // keep the flag
* 1d. Outliers — flag first (winsorize in Step 2)
egen wage_z = std(wage)
count if abs(wage_z) > 4
display "Flagged |z|>4 on wage: " r(N)
* 1e. Deduplicate on panel key
duplicates report worker_id year
duplicates tag worker_id year, gen(dup)
assert dup == 0 // hard-fail if panel key not unique
drop dup
* 1f. Merge with assert — never silently lose rows
merge m:1 firm_id using "firm_chars.dta", ///
assert(match using master) keep(master match) nogen
* 1g. Panel structure
xtset worker_id year // declares panel
xtdescribe // balance summary
tab year // observations per year
重要な原則:行の除外はすべて明示し、件数を数えて記録します。ステップ 2 以降のコマンドで、行を通知なく除外してはなりません。
ステップ 2 — 変数の構築と変換
詳しいパターンについては、references/02-data-transformation.md を参照してください。log/ihs/Box–Cox、グループ内の winsor2、xtile とカスタム区切り、egen のレシピ、時系列演算子(L., F., D., S.)、CPI デフレート、段階的導入 DID のタイミング構築を扱います。
* 2a. Log / IHS
gen log_wage = log(max(wage, 1)) // floor at 1
gen ihs_assets = asinh(assets) // handles 0 / negative
* 2b. Winsorize 1/99
winsor2 wage, cuts(1 99) suffix(_w1) by(year) // within-year winsorize
* 2c. Standardize
egen age_std = std(age)
* 2d. Categorical encoding (factor variables — use i. inside regressions)
* Explicit dummies only when needed for export
tab industry, gen(ind_)
drop ind_1 // base category
* 2e. Interactions & polynomials — use c. and i. inline in reg commands
gen age_sq = age^2
gen trt_x_edu = training * edu
* 2f. Panel operators (xtset is required for L./F./D. to work)
xtset worker_id year
gen log_wage_l1 = L.log_wage
gen log_wage_f1 = F.log_wage
gen d_log_wage = D.log_wage
* 2g. Within-unit mean (egen)
egen wage_mean_i = mean(log_wage), by(worker_id)
* 2h. Treatment timing for staggered DID
bysort worker_id (year): egen first_treat = min(cond(training==1, year, .))
gen rel_time = year - first_treat
replace rel_time = . if missing(first_treat) // never-treated = .
gen never_treated = missing(first_treat)
* 2i. Real values (CPI deflation)
merge m:1 year using "cpi.dta", keep(master match) nogen
sum cpi if year == 2010
gen wage_real = wage * r(mean) / cpi
ステップ 2.5 — 実証戦略(式と識別仮定を記述する)
これは AER 論文の核心です。コードを書く前に、式を明示的に記述し、識別仮定を述べてください。識別に関する曖昧な説明は、応用研究論文が査読者に却下される最も一般的な理由です。戦略は strategy.do(または .md)として保存し、日付入りのバージョン管理された成果物にしてください。係数を見た後で事後的に正当化を書くのではいけません。
式 × 識別仮定 × Stata 推定コマンド(判断表)
| デザイン | 推定式 | 識別仮定 | Stata 推定コマンド |
|---|---|---|---|
| 2×2 DID | Y_it = α_i + λ_t + β·D_it + X'γ + ε_it | X で条件付けた平行トレンド | reghdfe Y c.D#c.post X, absorb(i t) vce(cluster i) |
| イベントスタディ(CS/SA) | Y_it = α_i + λ_t + Σ_{e≠-1} β_e · 1{t-G_i = e} + ε_it | 予期なし + グループ・時点別 PT | csdid / eventstudyinteract / did_imputation |
| 2SLS | Y_i = α + β·D_i + X'γ + ε_i; D_i = π·Z_i + X'δ + u_i | 排除制約 + 関連性 + 単調性 | ivreg2 / ivreghdfe |
| シャープ RD | Y_i = α + β·1{X_i ≥ c} + f(X_i) + ε_i(局所多項式) | c における E[Y(0)|X] の連続性、操作なし | rdrobust(+ rddensity) |
| SCM | Ŷ_1t(0) = Σ_j ŵ_j Y_jt、τ_t = Y_1t − Ŷ_1t(0)(t≥T_0) | 介入前の適合 + 補間の妥当性 | synth / synth_runner / sdid |
| 観測可能な共変量に基づく選択(マッチング/IPW) | E[Y_i(d) | X_i] = E[Y_i | D=d, X_i] | 無交絡性 + オーバーラップ | teffects psmatch / ipw / aipw / ipwra、ebalance |
デザイン選択ガイド(ユーザーが迷っている場合)
┌─ running var + cutoff ───────────────── RDD (rdrobust)
│
├─ exogenous instrument Z ─────────────── IV/2SLS (ivreg2 / ivreghdfe)
data + question ─┤
├─ pre/post × treat/control ─┬ 2 periods ── 2×2 DID (reghdfe / xtreg)
│ └ staggered ── CS / SA / BJS (csdid / eventstudyinteract / did_imputation)
│
├─ 1 treated unit + donor pool + long pre ── SCM (synth / synth_runner / sdid)
│
├─ high-dim X, selection-on-observables ── ML causal (ddml / crforest — see §B)
│
└─ none of the above ──────────────────── matching + sensitivity (teffects + evalue)
事前登録用 strategy.do テンプレート
*--- strategy.do — empirical-strategy pre-registration ---
* Frozen `c(current_date)' `c(current_time)' (Git SHA: <paste>)
* Population: manufacturing workers, 2010–2020, balanced panel
* Treatment: training (binary, staggered adoption)
* Outcome: log_wage (CPI-deflated 2010 USD)
* Estimand: ATT on the treated, dynamic horizon -4..+4
*
* Estimating equation (paste from the §2.5 row that matches the design):
* log_wage_it = α_i + λ_t + Σ_{e≠-1} β_e · 1{t - G_i = e} + ε_it
*
* Identifying assumption:
* 1. No anticipation: E[Y_it(0) | t < G_i] = E[Y_it(0) | never-treated]
* 2. Group-time PT: Δ E[Y_it(0)] is the same across treatment cohorts
*
* Auto-flagged threats (must defend in §2):
* - Selection of G_i on Y_i(0) -> bacondecomp + honestdid sensitivity
* - Spillover across worker_id within firm -> cluster at firm_id, also try firm_id × year
* - Anticipation in the year before adoption -> include lead in event study
*
* Fallback estimators (Step 6 robustness):
* - eventstudyinteract (Sun-Abraham 2021)
* - did_imputation (Borusyak-Jaravel-Spiess 2024)
* - sdid (Synthetic DID)
ステップ 5/ステップ 6 を実行する前に、strategy.do をコミットしてください。このファイルの git log が、そのまま分析計画になります。
ステップ 3 — 記述統計と表 1
詳しいパターンについては、references/03-descriptive-stats.md を参照してください。SMD を含む層別表 1、asdoc / tabstat / balancetable、有意性を示す星印付き相関行列(pwcorr, sig star(.05))、グループ別ヒストグラム/kdensity、DID の動機付けに使う xtline、パネルのカバレッジを示す xtdescribe を扱います。
* 3a. Full-sample summary
local vars "log_wage age edu tenure training"
tabstat `vars', statistics(n mean sd min p25 p50 p75 max) columns(statistics)
* One-command Word/Excel output:
asdoc sum `vars', stat(N mean sd min median max) ///
save(tables/table1_full.docx) replace
* 3b. Stratified Table 1 (treated vs control + t-tests + SMDs)
balancetable training age edu tenure female ///
using "tables/table1_balance.tex", ///
vce(cluster firm_id) replace ///
varlabels pval
* Manual per-variable t-test + SMD:
foreach v of varlist age edu tenure {
qui sum `v' if training == 1
local m1 = r(mean); local sd1 = r(sd); local n1 = r(N)
qui sum `v' if training == 0
local m0 = r(mean); local sd0 = r(sd); local n0 = r(N)
local smd = (`m1' - `m0') / sqrt((`sd1'^2 + `sd0'^2)/2)
ttest `v', by(training)
display "`v': Δ=" %7.3f (`m1'-`m0') " SMD=" %7.3f `smd' " p=" %6.3f r(p)
}
* 3c. Correlation matrix with significance stars
pwcorr `vars', sig star(.05)
estout using "tables/corr.tex", replace ///
cells("b(star fmt(3))") style(tex) // alternative: estpost correlate
* 3d. Distribution plots
twoway (kdensity log_wage if training==1) ///
(kdensity log_wage if training==0), ///
legend(order(1 "Treated" 2 "Control")) ///
title("Log wage density by treatment") ///
saving(figures/kde_wage, replace)
graph export "figures/kde_wage.pdf", replace
* 3e. Time trends — the DID motivation plot
preserve
collapse (mean) log_wage, by(year training)
twoway (line log_wage year if training==1) ///
(line log_wage year if training==0), ///
xline(`policy_year', lpattern(dash)) ///
legend(order(1 "Treated" 2 "Control"))
graph export "figures/trend_did.pdf", replace
restore
* 3f. Panel coverage
xtdescribe
ステップ 3.5 — 識別グラフ(セクション「識別、図によるエビデンス」)
AER の慣例では、回帰表より先に識別図を示します。 点推定値を信頼するよう求める前に、PT が成立している/第1段階が強い/RD が明確に跳んでいることを、読者がグラフで確認できるようにしてください。このブロックでは figures/ に 1~2 枚の図を保存します。大部分の作業は、Stata コマンド 1 つと coefplot 1 つで済みます。
3.5.1 イベントスタディ図と数値による事前トレンド検定(DID 識別)
介入前の係数がおおむね 0(基準期間 −1 を 0 に正規化)であることが、平行トレンドの視覚的なエビデンスです。レビュー担当者が目視で判断する必要がないよう、図と数値による事前トレンド検定を組み合わせてください。
* Build relative-time factor variable, base at e = -1
gen rel = year - first_treat
replace rel = . if missing(first_treat) // never-treated dropped from event study
keep if inrange(rel, -4, 4) | missing(first_treat)
gen rel_p = rel + 5 // shift -4..4 → 1..9; ib4 means "base = -1"
* (a) Sun-Abraham via -eventstudyinteract- (preferred for staggered adoption)
forvalues k = 1/9 {
gen rel_d`k' = (rel_p == `k')
}
eventstudyinteract log_wage rel_d1 rel_d2 rel_d3 rel_d5 rel_d6 rel_d7 rel_d8 rel_d9, ///
cohort(first_treat) control_cohort(never_treated) ///
absorb(worker_id year) vce(cluster worker_id)
* (b) Coefficient figure with shaded CI + reference line at e=-1
coefplot, keep(rel_d*) vertical omitted ///
yline(0, lpattern(dash) lcolor(gs10)) xline(4.5, lpattern(dash)) ///
rename(rel_d1="-4" rel_d2="-3" rel_d3="-2" rel_d5="0" ///
rel_d6="1" rel_d7="2" rel_d8="3" rel_d9="4") ///
ciopts(recast(rcap)) levels(95) ///
xtitle("Years relative to treatment") ///
ytitle("Coefficient (ATT, 95% CI)") ///
title("Figure 2a. Event-study coefficients (95% CI; ref. e = -1)") ///
scheme(s2color)
graph export "figures/fig2a_event_study.pdf", replace
graph export "figures/fig2a_event_study.png", replace width(2400)
* (c) Numerical pre-trends F-test (joint zero on the leads e = -4..-2)
test rel_d1 rel_d2 rel_d3
display "Pre-trends F = " %5.2f r(F) " p = " %5.3f r(p)
* (d) Bacon decomposition figure (Goodman-Bacon 2021) — TWFE diagnostic
bacondecomp log_wage training, ddetail
* The -bacondecomp- output names the contaminated 2×2 weights.
* Save the auto-generated figure as figures/fig2a_bacon.pdf.
* (e) Callaway-Sant'Anna dynamic ATT (when -csdid- is the main estimator)
csdid log_wage age edu, ivar(worker_id) time(year) gvar(first_treat) ///
method(dripw) agg(event)
estat event, window(-4 4)
csdid_plot, title("Figure 2a-bis. Dynamic ATT (Callaway-Sant'Anna)")
graph export "figures/fig2a_csdid.pdf", replace
3.5.2 第1段階の F 統計量+散布図(IV の識別)
経験則:OLS 型の推論では第1段階の F ≥ 10、AR 相当の推論では F ≥ 23 です(Stock–Yogo/Lee 2022)。ivreg2 はデフォルトで CD/KP/弱 IV 統計量を報告します。ivregress の最小限の出力よりもはるかに有用です。
ivreg2 log_wage age edu (training = Z1 Z2), cluster(firm_id) first endog(training)
* Look for the line "Cragg-Donald Wald F" and "Kleibergen-Paap rk Wald F" —
* and "Anderson-Rubin Wald test" for weak-IV-robust CIs.
* First-stage scatter (binscatter — residualizes age + edu)
binscatter training Z1, controls(age edu) nquantiles(20) ///
xtitle("Excluded instrument Z1") ytitle("Pr(training)") ///
title("Figure 2b. First-stage relationship (residualized)") ///
savegraph("figures/fig2b_first_stage.pdf") replace
3.5.3 RD:McCrary 密度検定+標準的な RD プロット
RD を特徴づける図は rdplot です(CCT 方式のビン分割散布図と、両側それぞれの局所多項式フィット)。これに McCrary 操作検定を組み合わせます。これらを合わせて、(a)視覚的な不連続があるか、(b)カットオフで密度が連続しているか、という問いに答えます。
* (a) Canonical RD plot
rdplot outcome running_var, c(0) p(4) kernel(triangular) binselect(esmv) ///
graph_options(title("Figure 2c. RD plot") ///
ytitle("Outcome") xtitle("Running variable") ///
scheme(s2color))
graph export "figures/fig2c_rdplot.pdf", replace
* (b) McCrary density (manipulation test) — Cattaneo–Jansson–Ma 2018
rddensity running_var, c(0) plot ///
plot_options(title("Figure 2c-bis. McCrary density (manipulation test)"))
graph export "figures/fig2c_mccrary.pdf", replace
* (c) Covariate-adjusted continuity test (continuity of *covariates* at c)
foreach v of varlist age edu tenure {
rdrobust `v' running_var, c(0)
}
3.5.4 マッチング:ラブプロット(標準化差の前後比較)
teffects psmatch (log_wage) (training age edu tenure), atet
tebalance summarize // table of pre/post SMDs
tebalance density ps // density overlap plot — save as figures/fig2d_overlap.pdf
graph export "figures/fig2d_overlap.pdf", replace
* Or use -psmatch2- + -pstest- for the canonical love plot
psmatch2 training age edu tenure, out(log_wage) n(1) common
pstest age edu tenure, both graph // pre/post |std diff| with target |Δ|<10%
graph export "figures/fig2d_loveplot.pdf", replace
3.5.5 SCM:合成コントロールの推移+ギャッププロット
合成コントロール設計で標準的な図 2 は、処置時点を注記した、処置群と合成コントロールの時系列です。
synth log_wage age edu tenure, ///
trunit(1) trperiod(2015) fig keep("synth_results.dta", replace)
graph export "figures/fig2e_synth_trajectory.pdf", replace
* Synthetic DID variant
sdid log_wage worker_id year training, vce(bootstrap) graph g1on
graph export "figures/fig2e_sdid.pdf", replace
* Placebo gap distribution
synth_runner log_wage age edu tenure, ///
trunit(1) trperiod(2015) gen_vars
effect_graphs, trlinediff(0)
graph export "figures/fig2e_placebo_gaps.pdf", replace
識別に特化したチェック(DID の PT、弱 IV の F、RD の密度、マッチングの共通サポート)は、Step-5 の推定器内でも自動実行されます。ここで数値を重複して示す必要はありませんが、図は必ず作成してください。査読者はまず図に目を通します。
ステップ 4 — 診断統計検定
より詳細なパターンについては、references/04-statistical-tests.md を参照してください。Shapiro–Wilk、Jarque–Bera、Breusch–Pagan、White、Cook–Weisberg、Durbin–Watson、Breusch–Godfrey、Wooldridge の xtserial、Pesaran CD、xttest3、VIF、estat ovtest(RESET)、拡張 Dickey–Fuller、KPSS、Phillips–Perron、Hausman(FE 対 RE)、Sargan–Hansen、estat firststage(弱 IV)。
* Baseline OLS to anchor diagnostics
reg log_wage training age edu tenure
* 4a. Normality of residuals
predict resid, resid
swilk resid // Shapiro–Wilk (N ≤ 5000)
sktest resid // skewness + kurtosis test
* 4b. Heteroskedasticity
estat hettest // Breusch–Pagan / Cook–Weisberg
estat imtest, white // White's general test
* 4c. Autocorrelation (panel)
xtset worker_id year
xtreg log_wage training age edu tenure, fe
xtserial log_wage training age edu tenure // Wooldridge serial-correlation
xttest3 // modified Wald groupwise hetero
* 4d. Cross-sectional dependence (panel)
xtcsd, pesaran abs // Pesaran CD test
* 4e. Multicollinearity
quietly reg log_wage training age edu tenure
estat vif
* 4f. Model specification
estat ovtest // Ramsey RESET
linktest // Stata "linktest"
* 4g. Stationarity (time series)
dfuller log_wage, lags(4) trend // ADF
kpss log_wage, maxlag(4) notrend // KPSS
pperron log_wage, lags(4) // Phillips–Perron
* 4h. Panel unit root (multiple series)
xtunitroot ips log_wage, lags(aic 4) // Im–Pesaran–Shin
xtunitroot llc log_wage, lags(aic 4) // Levin–Lin–Chu
* 4i. Hausman (after running FE and RE)
qui xtreg log_wage training age edu, fe
estimates store fe
qui xtreg log_wage training age edu, re
estimates store re
hausman fe re, sigmamore
判定表:
| 検定 | 帰無仮説 | 棄却された場合 |
|---|---|---|
swilk / sktest | 残差は正規分布に従う | N が大きい場合:通常は無視します。N が小さい場合:ブートストラップを使用します |
estat hettest / imtest, white | 等分散 | vce(robust) または vce(cluster id) を使用します |
xtserial / xttest3 | パネル内の自己相関なし/グループごとの異分散なし | 単位でクラスタリングします |
xtcsd, pesaran | クロスセクション依存なし | Driscoll–Kraay または xtscc を使用します |
estat vif > 10 | — | 共線性のある説明変数を削除または統合します |
estat ovtest | モデルの特定は適切 | 多項式項/対数を追加します |
dfuller は棄却+kpss は棄却せず | 定常 | 水準のまま使用します |
dfuller は棄却せず | 単位根 | 1階差分を取るか、共和分を検定します |
hausman | RE は一致推定量 | FE を使用します |
Step 5 — ベースラインの実証モデリング(セクション 4:主な結果)
より深いパターン:references/05-modeling.md — 構文を含むすべての古典的推定量:reg、areg、xtreg、reghdfe、ivreg2 / ivregress / ivreghdfe、logit / probit / ppmlhdfe、csdid / did_imputation / eventstudyinteract / sdid / did_multiplegt_dyn、rdrobust / rddensity / rdmc、synth / synth_runner、psmatch2 / teffects psmatch|ipw|ipwra|aipw、ebalance、heckman、qreg。
応用論文の中でも特に密度の高いセクションです。現代の AER §4 には通常、複数回帰表が 2~3 点と係数プロットが 1 点含まれます。
- 表 2(主表):段階的に統制変数を追加し、4~6 列 — 以下の パターン A
- 表 2-bis(設計の比較):OLS / IV / DID / マッチングで同じ係数を提示 — パターン B
- 表 2-ter(複数アウトカム):同じ処置について複数のアウトカムを横並びで提示 — パターン C
- 図 3(coefplot):仕様ごとの β̂ と 95% CI を視覚的に要約
推定量の選択(必ず覚えてください。誤ると、気づかないまま意味のない結果が出ます):
- FE なし/低次元の FE が 1 つ →
reg y x1 x2, vce(cluster id)- 高次元 FE →
reghdfe y x1 x2, absorb(fe1 fe2) vce(cluster id)- 2 方向クラスタリング →
reghdfe ..., vce(cluster fe1 fe2)- 2SLS / IV →
ivreg2 y x (D = Z), cluster(id) first endog(D)(または高次元 FE + IV にはivreghdfe)- DID / イベントスタディ →
csdid/eventstudyinteract/did_imputation
識別戦略に基づいて推定量を選んでください:
Observational cross-section, selection on obs → reg + controls | teffects psmatch|ipwra
Observational panel, policy shock, parallel trends → csdid / did_imputation / eventstudyinteract / sdid
Exogenous instrument → ivreg2 / ivregress / ivreghdfe
Discontinuity in assignment rule → rdrobust (+ rddensity)
N=1 treated, long panel → synth / synth_runner
Selection on observables + heterogeneity → teffects aipw / ebalance
Binary outcome → logit / probit + margins
Count outcome → poisson / nbreg / ppmlhdfe
標準的なコマンド(outreg2 / esttab に相当する Stata のコマンドは主要な作業ツールです — eststo で 5~6 個の仕様を保存し、その後 esttab で 1 つの表にまとめます)。主なオプション:
keep(...) : list of coefficients to display (e.g. keep(training))
drop(...) : list of coefficients to suppress (controls / intercept)
mtitles("(1)" "(2)" ...) : column labels for the regression table
stats(N r2 r2_a, labels(...)) : footer rows
star(* 0.10 ** 0.05 *** 0.01) : AER stars
addnotes("...") : table footer (cluster level, FE absorbed, sample restrictions)
label booktabs : pretty-print + LaTeX booktabs borders
5.A パターン A — 段階的に統制変数を追加(標準的な表 2)
列をまたいで β̂ が安定していれば、観測可能な要因に基づく選択が推定値を左右している可能性は低くなります(Oster 2019 の選択安定性の考え方。定量化については Step 6.j を参照)。eststo m1...m6 + esttab は、Stata における outreg2 および R の modelsummary に相当します。
eststo clear
eststo m1: qui reg log_wage training, vce(cluster firm_id)
eststo m2: qui reg log_wage training age edu, vce(cluster firm_id)
eststo m3: qui reg log_wage training age edu tenure firm_size, vce(cluster firm_id)
eststo m4: qui reghdfe log_wage training age edu tenure firm_size, absorb(industry year) vce(cluster firm_id)
eststo m5: qui reghdfe log_wage training age edu tenure firm_size, absorb(worker_id year) vce(cluster firm_id)
eststo m6: qui reghdfe log_wage training age edu tenure firm_size, absorb(worker_id year i.industry#i.year) vce(cluster firm_id)
esttab m1 m2 m3 m4 m5 m6 using "tables/table2_main.tex", ///
replace se star(* 0.10 ** 0.05 *** 0.01) ///
label booktabs ///
mtitles("(1) Baseline" "(2) +Demog" "(3) +Labor-mkt" "(4) Ind×Yr FE" "(5) Worker FE" "(6) Ind×Yr × Worker FE") ///
stats(N r2 r2_a, labels("N" "R²" "Adj. R²")) ///
addnotes("Cluster-robust SE at firm_id in parentheses." ///
"* p<0.10, ** p<0.05, *** p<0.01.")
* Word version: same call with .rtf extension.
AER の慣例:すべての統制変数を表示します — すべてのパラメーターが見えるよう、
keep()もdrop()も渡しません。 主要係数のみの表を意図する場合(例:交互作用形式による異質性分析、IV の第一段階トリプレット)はkeep(training)のみを使用します。論文の見栄えのために定数項を非表示にしたい場合に限り、drop(_cons)のみを使用します。
5.B パターン B — 設計の比較(表 2-bis)
複数の識別戦略のもとで、関心のある同じ係数を提示します。これは AER で信頼性を示すための最も重要な方法です。それぞれ異なる識別仮定に基づく設計から、収束する証拠を示します。
eststo clear
eststo ols: qui reghdfe log_wage training age edu tenure, absorb(industry year) vce(cluster firm_id)
eststo iv: qui ivreg2 log_wage age edu tenure (training = Z1 Z2), cluster(firm_id)
eststo did: qui csdid log_wage age edu tenure, ivar(worker_id) time(year) gvar(first_treat) method(dripw) agg(group)
eststo psm: qui teffects psmatch (log_wage) (training age edu tenure), atet
eststo ebal: qui ebalance training age edu tenure
qui reg log_wage training age edu tenure [pw=_webal], vce(cluster firm_id)
eststo ebal_main
esttab ols iv did psm ebal_main using "tables/table2b_designs.tex", ///
replace se star(* 0.10 ** 0.05 *** 0.01) label booktabs ///
keep(training) ///
mtitles("(1) OLS+FE" "(2) 2SLS" "(3) CS-DID" "(4) PSM" "(5) Entropy bal.") ///
stats(N, labels("N")) ///
addnotes("Convergent evidence: same β̂ under five identification strategies.")
5.C パターン C — 複数アウトカム表(同じ X、複数の Y)
1 つの処置に対して、複数のアウトカムを扱います。各列に Y の名前を表示するには mtitles を使用します。
eststo clear
foreach y of varlist log_wage weeks_employed left_firm promoted {
eststo `y': qui reghdfe `y' training age edu tenure, ///
absorb(industry year) vce(cluster firm_id)
}
esttab log_wage weeks_employed left_firm promoted using "tables/table2c_multi_outcome.tex", ///
replace se star(* 0.10 ** 0.05 *** 0.01) label booktabs ///
keep(training) ///
mtitles("Log wage" "Weeks empl." "Left firm" "Promoted") ///
stats(N r2, labels("N" "R²")) ///
addnotes("Each column is a separate regression on the labelled outcome.")
5.D パターン D — パネル A / パネル B の積み重ね表
同じモデル群について、2 つの期間(短期/長期)または 2 つのサンプル(2015 年以前/2015 年以降)を扱います。2 回の esttab 呼び出しと texdoc の接続を使って縦に積み重ねるか、esttab ..., refcat() を使ってパネル見出しを挿入します。
* Panel A — short-run (1 year horizon)
eststo clear
eststo a1: qui reghdfe log_wage_t1 training X, absorb(industry year) vce(cluster firm_id)
eststo a2: qui reghdfe log_wage_t1 training X, absorb(worker_id year) vce(cluster firm_id)
* Panel B — long-run (5 year horizon)
eststo b1: qui reghdfe log_wage_t5 training X, absorb(industry year) vce(cluster firm_id)
eststo b2: qui reghdfe log_wage_t5 training X, absorb(worker_id year) vce(cluster firm_id)
* First panel — write
esttab a1 a2 using "tables/table2d_horizons.tex", replace ///
se star(* 0.10 ** 0.05 *** 0.01) label booktabs ///
keep(training) mtitles("(1) Industry FE" "(2) Worker FE") ///
refcat(training "\textbf{Panel A. Short-run (1 year)}", nolabel) ///
stats(N r2, labels("N" "R²"))
* Second panel — append
esttab b1 b2 using "tables/table2d_horizons.tex", append ///
se star(* 0.10 ** 0.05 *** 0.01) label booktabs ///
keep(training) mtitles("(1) Industry FE" "(2) Worker FE") ///
refcat(training "\textbf{Panel B. Long-run (5 years)}", nolabel) ///
stats(N r2, labels("N" "R²"))
5.E パターン E — IV 報告のトリプレット(第一段階/誘導形/2SLS)
教科書的な AER の IV 表では、第一段階、誘導形、2SLSを 3 列で提示し、読者が Wald 比 = RF / FS を確認できるようにします。
eststo clear
eststo fs: qui reghdfe training Z age edu, absorb(industry year) vce(cluster firm_id) // first stage
eststo rf: qui reghdfe log_wage Z age edu, absorb(industry year) vce(cluster firm_id) // reduced form
eststo iv: qui ivreghdfe log_wage age edu (training = Z), absorb(industry year) cluster(firm_id) first
esttab fs rf iv using "tables/table2e_iv_triplet.tex", ///
replace se star(* 0.10 ** 0.05 *** 0.01) label booktabs ///
keep(Z training) ///
mtitles("(1) First stage" "(2) Reduced form" "(3) 2SLS") ///
stats(N r2 widstat, labels("N" "R²" "First-stage F (KP)")) ///
addnotes("Wald ratio: $\hat\beta_{2SLS} = \hat\beta_{RF} / \hat\pi_{FS}$.")
IV トリプレットでは、意図的に主要変数に絞ります。 読者が Wald 比を一目で確認できるよう、Z と内生変数のみを表示します。査読者から係数をすべて提示するよう求められた場合に限り、
keep(Z training)を削除します。
5.F パターン F — csdid / synth_runner / teffects による因果推論の主分析
DID / SCM / マッチングの主分析では、最新の Stata 推定量が、推定値と自動的なプラセボ検定/事前トレンド/オーバーラップ診断を一体化して返します。推定量自体のレポートを使い、その後 eststo + esttab に渡します。
* CS-DID with pre-trends test
csdid log_wage age edu tenure, ivar(worker_id) time(year) gvar(first_treat) ///
method(dripw) agg(group) saverif(csdid_rif.dta)
estat pretrend // joint zero on pre-period leads
estat simple // ATT(g) summary
estat event, window(-4 4) // dynamic ATT
csdid_estat aggte, type(group) saverif(att_g.dta)
eststo m_csdid
* Synth-runner with 50 placebo treated units → exact p-value on β̂_treated
synth_runner log_wage age edu tenure, trunit(1) trperiod(2015) gen_vars
single_treatment_graphs, do_color(red)
effect_graphs, trlinediff(0)
* Reports exact p-value from the placebo distribution.
* Teffects AIPW with overlap + balance check
teffects aipw (log_wage age edu tenure) (training age edu tenure)
tebalance summarize
eststo m_aipw
5.G パターン G — サブグループの esttab(表 3。Step 7 を参照)
サブグループごとに 1 列を設けます。詳しいコードは §Step 7 — 異質性を参照してください。
5.H パターン H — 堅牢性のマスター(表 A1、ステップ 6 を参照)
すべての堅牢性仕様をベースラインの隣に並べます。詳しいコードは §ステップ 6 — 堅牢性のマスターを参照してください。
標準的な推定コマンド(基礎となるプリミティブ)
* 5a. OLS with cluster-robust SE
reg log_wage training age edu tenure, vce(cluster firm_id)
eststo ols_m1
* 5b. Two-way FE — reach for reghdfe (absorb HD FE; clusters any level)
reghdfe log_wage training age edu tenure, ///
absorb(worker_id year) vce(cluster worker_id)
eststo fe_m1
* Multi-way clustering
reghdfe log_wage training, absorb(worker_id year) ///
vce(cluster worker_id firm_id)
* High-dim FE (industry × year, firm × state)
reghdfe log_wage training, absorb(worker_id i.industry#i.year) ///
vce(cluster firm_id)
* 5c. 2×2 DID
reg log_wage i.treated##i.post age edu, vce(cluster worker_id)
* Or with absorbed FE:
reghdfe log_wage c.treated#c.post, absorb(worker_id year) ///
vce(cluster worker_id)
* 5d. Event study (dynamic DID, base period = -1)
* Build relative-time factor var, base at k = -1:
gen rel = rel_time + 10 // shift so -10..10 → 0..20
replace rel = 0 if missing(rel_time) // never-treated → bin 0
* (preferable: use -eventstudyinteract- or -did_imputation- — see reference 5.4)
reghdfe log_wage ib9.rel, absorb(worker_id year) vce(cluster worker_id)
coefplot, keep(*.rel) vertical omitted ///
yline(0) xline(9.5, lpattern(dash)) ///
xtitle("Years relative to treatment") ytitle("Coefficient (ATT)")
graph export "figures/event_study.pdf", replace
* 5e. Staggered DID — modern estimators (see references/05-modeling.md §5.4)
* Callaway–Sant'Anna (2021):
csdid log_wage, ivar(worker_id) time(year) gvar(first_treat) ///
method(dripw) agg(group)
* Sun & Abraham (2021):
eventstudyinteract log_wage rel_dummies_*, ///
cohort(first_treat) control_cohort(never_treated) ///
absorb(worker_id year) vce(cluster worker_id)
* Borusyak–Jaravel–Spiess (2024) imputation:
did_imputation log_wage worker_id year first_treat, ///
allhorizons pretrend(5)
* Synthetic DID (Arkhangelsky et al. 2021):
sdid log_wage worker_id year training, vce(bootstrap) ///
graph g1on g1_opt(ytitle("log wage"))
* 5f. IV / 2SLS — ivreg2 is the de-facto standard (full diagnostics)
ivreg2 log_wage age edu (training = draft_lottery), ///
cluster(firm_id) first endog(training)
* ivreghdfe for HD FE with IV:
ivreghdfe log_wage age (training = draft_lottery), ///
absorb(worker_id year) cluster(worker_id) first
* 5g. Sharp RD
rdrobust outcome running_var, c(0) kernel(triangular) bwselect(mserd)
rdplot outcome running_var, c(0)
* Fuzzy RD
rdrobust outcome running_var, c(0) fuzzy(treatment)
* Density test (McCrary / Cattaneo et al.)
rddensity running_var, c(0)
* 5h. Binary outcome — always follow with margins
logit employed training age edu, vce(cluster firm_id)
margins, dydx(training) atmeans
* 5i. Count outcome with HD FE
ppmlhdfe citations training age, absorb(firm_id year) ///
cluster(firm_id)
* 5j. Quantile regression
qreg log_wage training age edu, quantile(0.5)
sqreg log_wage training age edu, quantile(0.1 0.25 0.5 0.75 0.9) reps(500)
ステップ 6 — 堅牢性バッテリー
詳しいパターン:references/06-robustness.md — eststo/esttab による段階的な仕様 M1–M6、TWFE のバイアスに対する bacondecomp、honestdid(Rambachan–Roth)、ワイルドクラスター・ブートストラップの boottest、ランダム化推論の ritest、Romano–Wolf 法の rwolf、代替のクラスターレベル、Oster δ*、プラセボのタイミング、サブサンプル分割、ループによる仕様曲線。
* 6a. Progressive specifications (M1 → M6)
eststo clear
eststo m1: qui reg log_wage training, vce(cluster firm_id)
eststo m2: qui reg log_wage training age edu, vce(cluster firm_id)
eststo m3: qui reghdfe log_wage training age edu tenure, ///
absorb(worker_id) vce(cluster worker_id)
eststo m4: qui reghdfe log_wage training age edu tenure, ///
absorb(worker_id year) vce(cluster worker_id)
eststo m5: qui reghdfe log_wage training age edu tenure, ///
absorb(worker_id year region) vce(cluster worker_id)
eststo m6: qui reghdfe log_wage training age edu tenure, ///
absorb(worker_id year i.industry#i.year) vce(cluster worker_id)
esttab m1 m2 m3 m4 m5 m6 using "tables/table_main.tex", ///
replace se star(* 0.10 ** 0.05 *** 0.01) ///
stats(N r2 r2_a, labels("N" "R²" "Adj. R²")) ///
label booktabs
* 6b. Alternative cluster levels
foreach c in worker_id firm_id industry state {
qui reghdfe log_wage training, absorb(worker_id year) vce(cluster `c')
display "cluster=`c' b=" _b[training] " se=" _se[training]
}
* 6c. Wild cluster bootstrap (few clusters)
qui reghdfe log_wage training, absorb(worker_id year) vce(cluster state)
boottest training, cluster(state) reps(9999) seed(42)
* 6d. Subsample splits
foreach mask in "female==0" "female==1" "age<40" "age>=40" {
qui reghdfe log_wage training if `mask', ///
absorb(worker_id year) vce(cluster worker_id)
display "`mask': b=" _b[training] " se=" _se[training] " N=" e(N)
}
* 6e. Placebo timing
gen fake_first = first_treat - 3
gen fake_post = (year >= fake_first)
preserve
keep if year < first_treat // drop real post-period
reghdfe log_wage fake_post, absorb(worker_id year) ///
vce(cluster worker_id)
restore
* 6f. Randomization inference (permutation)
ritest training _b[training], reps(1000) seed(0) ///
strata(worker_id): reghdfe log_wage training, ///
absorb(worker_id year) vce(cluster worker_id)
* 6g. Romano–Wolf multiple testing
rwolf log_wage employed hours_worked, indepvar(training) ///
controls(age edu) reps(500) seed(42) method(reghdfe) ///
fe(worker_id year) cluster(worker_id)
* 6h. TWFE bias diagnosis — Goodman-Bacon decomposition
bacondecomp log_wage training, ddetail
* 6i. Parallel trends sensitivity — HonestDiD
* (after running the event study and saving b/V)
honestdid, pre(1/4) post(5/9) mvec(0(0.1)0.5)
* 6j. Oster (2019) δ*
qui reg log_wage training // short
scalar bs = _b[training]; scalar r2s = e(r2)
qui reghdfe log_wage training age edu tenure, absorb(worker_id year)
scalar bl = _b[training]; scalar r2l = e(r2)
psacalc delta training, mcontrol(age edu tenure) rmax(1.3*r2l)
6.k パターン H — 堅牢性マスター表(表 A1、チェックごとに 1 列)
標準的な AER の付録表 A1 では、すべての堅牢性仕様をベースラインの隣に並べ、β̂ が維持されることを査読者が一目で確認できるようにします。eststo の結果リストを動的に作成します。
eststo clear
* (1) Baseline
eststo base: qui reghdfe log_wage training age edu tenure, ///
absorb(industry year) vce(cluster firm_id)
* (2) Drop top 1% of wage
qui sum wage, detail
eststo no99: qui reghdfe log_wage training age edu tenure if wage < r(p99), ///
absorb(industry year) vce(cluster firm_id)
* (3) Balanced panel only
preserve
keep if e(sample) // start from baseline sample
bysort worker_id: egen n_obs = count(year)
qui sum n_obs, detail
keep if n_obs == r(max)
eststo balpan: qui reghdfe log_wage training age edu tenure, ///
absorb(industry year) vce(cluster firm_id)
restore
* (4) Drop early adopting cohorts
eststo dropearly: qui reghdfe log_wage training age edu tenure if first_treat > 2008, ///
absorb(industry year) vce(cluster firm_id)
* (5) Worker FE absorbed (selection on FE-removable unobservables)
eststo wfe: qui reghdfe log_wage training age edu tenure, ///
absorb(worker_id year) vce(cluster firm_id)
* (6) Two-way cluster (firm × year)
eststo cl2way: qui reghdfe log_wage training age edu tenure, ///
absorb(industry year) vce(cluster firm_id year)
* (7) Wild cluster bootstrap (after running the baseline)
qui reghdfe log_wage training age edu tenure, absorb(industry year) vce(cluster firm_id)
boottest training, cluster(firm_id) reps(9999) seed(42) nograph // returns CI
* Note bootstrapped p-value in the row footer of the master table.
* (8) Log outcome
eststo logy: qui reghdfe log_log_wage training age edu tenure, ///
absorb(industry year) vce(cluster firm_id)
* (9) IHS outcome (handles zeros)
gen ihs_wage = asinh(wage)
eststo ihsy: qui reghdfe ihs_wage training age edu tenure, ///
absorb(industry year) vce(cluster firm_id)
* (10) PSM-weighted outcome
qui psmatch2 training age edu tenure, out(log_wage) n(1) common
eststo psm: qui reg log_wage training age edu tenure if _support == 1, vce(cluster firm_id)
* (11) Entropy balance
ebalance training age edu tenure
eststo ebal: qui reg log_wage training age edu tenure [pw=_webal], vce(cluster firm_id)
esttab base no99 balpan dropearly wfe cl2way logy ihsy psm ebal ///
using "tables/tableA1_robustness.tex", ///
replace se star(* 0.10 ** 0.05 *** 0.01) label booktabs ///
keep(training) ///
mtitles("(1) Baseline" "(2) Drop top 1%" "(3) Balanced" "(4) Drop early" ///
"(5) Worker FE" "(6) 2-way cluster" "(7) log Y" "(8) IHS Y" ///
"(9) PSM" "(10) Entropy bal.") ///
stats(N r2, labels("N" "R²")) ///
addnotes("Each column is one robustness check. β̂ on training is the focal coefficient.")
6.l Stata での仕様曲線(Simonsohn–Simmons–Nelson 2020)
esttab に仕様曲線の標準機能はありません。{統制変数 × サンプル × アウトカム変換 × SE タイプ} の組み合わせをループ処理し、各 β̂ と 95% CI をフレームに保存してからプロットします。
capture frame drop spec
frame create spec spec_id b se lo hi label
local id 0
foreach controls in "age" "age edu" "age edu tenure" "age edu tenure firm_size" {
foreach trans in "log_wage" "ihs_wage" { // outcome transforms
foreach mask in "1" "industry==\"manuf\"" "wage < r(p99)" { // subsamples
foreach cl in "firm_id" "firm_id year" { // SE types
qui reghdfe `trans' training `controls' if `mask', ///
absorb(industry year) vce(cluster `cl')
local ++id
local b = _b[training]
local se = _se[training]
local lo = `b' - 1.96*`se'
local hi = `b' + 1.96*`se'
frame post spec (`id') (`b') (`se') (`lo') (`hi') ("c=`controls'/y=`trans'/s=`mask'/cl=`cl'")
}
}
}
}
frame change spec
sort b
gen rank = _n
twoway (rcap lo hi rank) (scatter b rank), ///
yline(0, lpattern(dash) lcolor(gs10)) ///
xtitle("Specification (sorted by β̂)") ytitle("Coefficient on training") ///
title("Figure 5. Specification curve") ///
legend(off) scheme(s2color)
graph export "figures/fig5_spec_curve.pdf", replace
graph export "figures/fig5_spec_curve.png", replace width(2400)
frame change default
現代の AER の査読者からのレターでは、「仕様 X ではどうなるか」とよく問われます。仕様曲線を使えば、そうした質問すべてに一度に答えられます。
6.m 感度分析ダッシュボード(HonestDiD + Oster + E-value、1 ブロック)
DID の主要結果について、図を 1 つ(HonestDiD による部分識別境界)と、感度統計量の行を 1 つ(Oster δ + E-value)作成します。
* (a) HonestDiD — Rambachan-Roth (2023) bound on β̂ under bounded PT violation
* Re-run the event study and store b/V:
qui eventstudyinteract log_wage rel_d1-rel_d9, ///
cohort(first_treat) control_cohort(never_treated) ///
absorb(worker_id year) vce(cluster worker_id)
honestdid, pre(rel_d1 rel_d2 rel_d3) post(rel_d5 rel_d6 rel_d7 rel_d8 rel_d9) ///
mvec(0(0.1)0.5) coefplot
graph export "figures/fig6_honestdid.pdf", replace
* (b) Oster δ (Pattern: how big would selection on unobservables have to be?)
qui psacalc delta training, mcontrol(age edu tenure firm_size) rmax(1.3)
display "Oster δ for β=0: " r(delta)
* (c) E-value (Linden-Mathur 2020) — for binary / risk-ratio outcomes
* Convert OLS coefficient to risk-ratio scale first if applicable.
evalue rr, est(1.45) lcl(1.10) ucl(1.91)
* → reports the minimum strength of unmeasured confounding to nullify the result.
ステップ 7 — 追加分析(メカニズム/異質性/媒介/調整)
詳しいパターン:references/07-further-analysis.md — 因子変数の交互作用、margins/marginsplot、三重差分(DDD)、アウトカム・ラダー、medsem/Baron–Kenny、非線形媒介分析の khb(Karlson–Holm–Breen)、xtile またはスプラインによる用量反応、サブグループ別イベントスタディ。
* 7a. Heterogeneity via interaction — coefficient IS the heterogeneity test
reghdfe log_wage c.training##i.female age edu, ///
absorb(worker_id year) vce(cluster worker_id)
margins, dydx(training) at(female=(0 1))
marginsplot, title("Marginal effect of training by gender") ///
ytitle("dY/d(training)")
graph export "figures/het_female.pdf", replace
* Continuous moderator
reghdfe log_wage c.training##c.tenure age edu, ///
absorb(worker_id year) vce(cluster worker_id)
margins, dydx(training) at(tenure=(0(2)20))
marginsplot
* 7b. Subgroup estimation + Wald test of equality
eststo clear
eststo m_male: qui reghdfe log_wage training if female==0, ///
absorb(worker_id year) vce(cluster worker_id)
eststo m_female: qui reghdfe log_wage training if female==1, ///
absorb(worker_id year) vce(cluster worker_id)
suest m_male m_female // joint covariance
test [m_male_mean]training = [m_female_mean]training // Wald test
* 7c. Triple difference (DDD)
reghdfe log_wage c.treated##c.post##c.high_exposure, ///
absorb(worker_id year) vce(cluster firm_id)
* coefficient on treated#post#high_exposure IS the differential DID
* 7d. Outcome ladder
eststo clear
foreach y of varlist hours_worked productivity log_wage {
eststo: qui reghdfe `y' training, ///
absorb(worker_id year) vce(cluster worker_id)
}
esttab using "tables/mechanism_ladder.tex", replace ///
se label booktabs
* 7e. Mediation — Baron–Kenny (manual)
qui reghdfe log_wage training age edu, absorb(worker_id year)
scalar c = _b[training]
qui reghdfe hours_worked training age edu, absorb(worker_id year)
scalar a = _b[training]
qui reghdfe log_wage training hours_worked age edu, absorb(worker_id year)
scalar b_m = _b[hours_worked]
scalar cprim = _b[training]
display "Total = " c " Direct = " cprim " Indirect a*b = " a*b_m
* Or via -medsem- (for SEM-based mediation with bootstrap CI)
medsem, indep(training) med(hours_worked) dep(log_wage) ///
mcreps(1000)
* 7f. CATE via Nonparametric (grf) — typically fall back to Python econml
* See references/07-further-analysis.md §7.7 for the rpy2-style bridge.
* 7g. Dose-response (continuous treatment, decile bins)
xtile dose10 = training_hours, nq(10)
reghdfe log_wage i.dose10 age edu, absorb(worker_id year) vce(cluster worker_id)
margins i.dose10
marginsplot, recast(connected) ytitle("Predicted log wage") ///
xtitle("Training-hours decile")
graph export "figures/dose_response.pdf", replace
ステップ 8 — 論文用の表と図
このステップは必須です — すべての分析実行で、このスキルの先頭にある デフォルト出力仕様 で定義された必須の表 5 つ(T1–T5)と図 4 つ(F1–F4)をすべて作成します。「回帰はすでに実行した」という理由でステップ 8 を省略しないでください。係数だけで表と図がない結果は、応用経済学における成果の伝え方ではありません。
詳しいパターン:references/08-tables-plots.md — 回帰表用の esttab と outreg2、係数プロット、イベントスタディ、フォレストプロット用の coefplot、交互作用用の marginsplot、残差化散布図用の binscatter、RD 用の rdplot、twoway とグラフの結合、Stata のスキーム/グラフオプション、LaTeX/Word/Excel へのエクスポート。
* ============================================================
* 8a. ★ TABLE 2 — Main results, multi-column regression M1→M6
* (the centerpiece of every economics paper)
* ============================================================
esttab m1 m2 m3 m4 m5 m6 using "tables/table2_main.tex", ///
replace ///
se star(* 0.10 ** 0.05 *** 0.01) ///
stats(N r2 r2_a fe_worker fe_year fe_indyr, ///
labels("N" "R²" "Adj. R²" "Worker FE" "Year FE" "Industry×Year FE")) ///
keep(training age edu tenure) ///
order(training age edu tenure) ///
mtitles("(1) Raw" "(2) +Demog" "(3) +Tenure" "(4) +Unit FE" "(5) +2-way FE" "(6) +Ind×Yr FE") ///
label booktabs nonumbers noobs ///
addnotes("Cluster-robust standard errors at worker_id level in parentheses." ///
"* p<0.10, ** p<0.05, *** p<0.01.")
* Word version
esttab m1 m2 m3 m4 m5 m6 using "tables/table2_main.rtf", replace ///
se star(* 0.10 ** 0.05 *** 0.01) label ///
mtitles("(1)" "(2)" "(3)" "(4)" "(5)" "(6)")
* outreg2 — alternative (one-line, broad compatibility)
* reghdfe log_wage training age edu tenure, absorb(worker_id year)
* outreg2 using "tables/table2_main_outreg2.doc", replace label dec(3) ///
* addtext(Worker FE, YES, Year FE, YES)
* ============================================================
* 8b. TABLE 1 — Summary statistics & balance
* ============================================================
balancetable training age edu tenure female ///
using "tables/table1_balance.tex", ///
vce(cluster firm_id) replace ///
varlabels pval booktabs
asdoc sum log_wage training age edu tenure female, ///
by(training) stat(N mean sd min median max) ///
save(tables/table1_balance.rtf) replace
* ============================================================
* 8c. TABLE 3 — Mechanism / outcome ladder (3+ outcomes)
* ============================================================
eststo clear
foreach y of varlist hours_worked productivity log_wage {
eststo: qui reghdfe `y' training age edu tenure, ///
absorb(worker_id year) vce(cluster worker_id)
}
esttab using "tables/table3_mechanism.tex", replace ///
se star(* 0.10 ** 0.05 *** 0.01) label booktabs ///
mtitles("Hours worked" "Productivity" "Log wage") ///
keep(training) ///
addnotes("Each column is a separate regression of the labelled outcome on training," ///
"with worker and year FE and cluster-robust SE at worker_id.")
* ============================================================
* 8d. TABLE 4 — Heterogeneity (subgroup × main coef + Wald)
* ============================================================
eststo clear
eststo all: qui reghdfe log_wage training, ///
absorb(worker_id year) vce(cluster worker_id)
eststo male: qui reghdfe log_wage training if female==0, ///
absorb(worker_id year) vce(cluster worker_id)
eststo female: qui reghdfe log_wage training if female==1, ///
absorb(worker_id year) vce(cluster worker_id)
eststo young: qui reghdfe log_wage training if age<40, ///
absorb(worker_id year) vce(cluster worker_id)
eststo old: qui reghdfe log_wage training if age>=40, ///
absorb(worker_id year) vce(cluster worker_id)
eststo manuf: qui reghdfe log_wage training if industry=="manufacturing", ///
absorb(worker_id year) vce(cluster worker_id)
esttab all male female young old manuf using "tables/table4_heterogeneity.tex", ///
replace se star(* 0.10 ** 0.05 *** 0.01) label booktabs ///
mtitles("All" "Female=0" "Female=1" "Age<40" "Age≥40" "Manuf.") ///
keep(training) ///
addnotes("Cluster-robust SE at worker_id. Wald p-values for cross-subgroup equality" ///
"(via -suest-) should accompany this table — see references/07.")
* ============================================================
* 8e. TABLE 5 — Robustness battery (alt SE / cluster / sample / placebo)
* ============================================================
eststo clear
eststo base: qui reghdfe log_wage training, absorb(worker_id year) vce(cluster worker_id)
eststo cl_firm: qui reghdfe log_wage training, absorb(worker_id year) vce(cluster firm_id)
eststo cl_2way: qui reghdfe log_wage training, absorb(worker_id year) vce(cluster worker_id firm_id)
eststo wins: qui reghdfe log_wage_w1 training, absorb(worker_id year) vce(cluster worker_id)
eststo dropmf: qui reghdfe log_wage training if industry!="manufacturing", ///
absorb(worker_id year) vce(cluster worker_id)
eststo placebo: qui reghdfe log_wage fake_post if year < first_treat, ///
absorb(worker_id year) vce(cluster worker_id)
esttab base cl_firm cl_2way wins dropmf placebo using "tables/table5_robustness.tex", ///
replace se star(* 0.10 ** 0.05 *** 0.01) label booktabs ///
mtitles("Baseline" "Cluster=Firm" "2-way Cluster" "Winsor 1/99" "Drop Manuf." "Placebo (-3 yr)") ///
keep(training fake_post)
* ============================================================
* 8f. ★ FIGURE 3 — Coefficient plot across M1→M6
* ============================================================
coefplot m1 m2 m3 m4 m5 m6, keep(training) ///
vertical yline(0, lpattern(dash)) ///
ciopts(recast(rcap)) ///
levels(95) ///
ylabel(, angle(0)) ///
xtitle("Specification") ytitle("Coefficient on training (95% CI)") ///
title("Effect of training across specifications") ///
scheme(s2color)
graph export "figures/fig3_coefplot.pdf", replace
graph export "figures/fig3_coefplot.png", replace width(2400)
* ============================================================
* 8g. FIGURE 2 — Event-study plot (dynamic DID, base period = -1)
* ============================================================
* (after running -eventstudyinteract- or -csdid- or reghdfe with relative-time factor)
coefplot, keep(*.rel) vertical omitted ///
xline(9.5, lpattern(dash)) yline(0, lpattern(dash)) ///
xtitle("Years relative to treatment") ///
ytitle("Coefficient (ATT, 95% CI)") ///
title("Event study: dynamic effect of training") ///
ciopts(recast(rcap)) ///
scheme(s2color)
graph export "figures/fig2_event_study.pdf", replace
graph export "figures/fig2_event_study.png", replace width(2400)
* ============================================================
* 8h. FIGURE 4 — Sensitivity / robustness curve
* (HonestDiD post-DID; or forest plot of robustness battery)
* ============================================================
* HonestDiD sensitivity (after the event study with stored b/V):
honestdid, pre(1/4) post(5/9) mvec(0(0.1)0.5) coefplot
graph export "figures/fig4_sensitivity.pdf", replace
graph export "figures/fig4_sensitivity.png", replace width(2400)
* Alternative: forest plot of subgroup / robustness coefficients
* coefplot (all, label(All)) (male, label(Male)) (female, label(Female)) ///
* (young, label(Age<40)) (old, label(Age≥40)) (manuf, label(Manuf.)), ///
* keep(training) xline(0, lpattern(dash)) ciopts(recast(rcap)) ///
* title("Heterogeneity forest plot")
* graph export "figures/fig4_forest.pdf", replace
* ============================================================
* 8i. FIGURE 1 — Trend / motivation (treated vs control over time)
* ============================================================
preserve
collapse (mean) log_wage, by(year training)
twoway (line log_wage year if training==1, lcolor(navy) lwidth(medthick)) ///
(line log_wage year if training==0, lcolor(cranberry) lwidth(medthick)), ///
xline(`policy_year', lpattern(dash) lcolor(gs8)) ///
legend(order(1 "Treated" 2 "Control") rows(1) position(6)) ///
xtitle("Year") ytitle("Mean log wage") ///
title("Treated vs control trend") ///
scheme(s2color)
graph export "figures/fig1_trend.pdf", replace
graph export "figures/fig1_trend.png", replace width(2400)
restore
* ============================================================
* 8j. Auxiliary plots (optional — produce when relevant to design)
* ============================================================
* Binscatter — residualized scatter
binscatter log_wage tenure, controls(age edu female) nquantiles(20) ///
savegraph("figures/figA_binscatter.pdf") replace
* RD plot (only when running_var exists)
* rdplot outcome running_var, c(0) ///
* graph_options(title("Effect of eligibility") ///
* ytitle("Outcome") xtitle("Running variable"))
* graph export "figures/figA_rdplot.pdf", replace
* Bacon decomposition plot — TWFE diagnostic
* bacondecomp log_wage training, ddetail
* graph export "figures/figA_bacon.pdf", replace
* ============================================================
* 8k. Graph theme (consistent styling across all figures)
* ============================================================
set scheme s2color
* or the modern: set scheme white_tableau (from -schemepack-)
成果物のチェックリスト(実行完了を宣言する前に確認してください):
[ ] tables/table1_balance.tex [ ] figures/fig1_trend.pdf
[ ] tables/table2_main.tex ★ [ ] figures/fig2_event_study.pdf
[ ] tables/table3_mechanism.tex [ ] figures/fig3_coefplot.pdf
[ ] tables/table4_heterogeneity.tex
[ ] tables/table5_robustness.tex [ ] figures/fig4_sensitivity.pdf
[ ] tables/tableA1_robustness.tex [ ] figures/fig5_spec_curve.pdf
[ ] artifacts/sample_construction.json (footnote 4)
[ ] artifacts/data_contract.json
[ ] artifacts/result.json (reproducibility stamp — see 8l)
8l. 再現性スタンプ
ジャーナルの再現性確認担当者(または将来の共著者)が主要な数値を再現するために必要な唯一の成果物です。Stata のバージョン、シード、データセットのハッシュ、ベースラインの係数 + CI、プロトコル/契約への参照先を保存します。
* After the headline regression has run as `eststo base`:
qui estimates restore base
matrix b = e(b); matrix V = e(V)
local b_hat = b[1, "training"]
local se = sqrt(V["training","training"])
local lo = `b_hat' - 1.96 * `se'
local hi = `b_hat' + 1.96 * `se'
file open f using "artifacts/result.json", write replace
file write f "{" _n
file write f `" "stata_version": "`c(stata_version)'","' _n
file write f `" "current_date": "`c(current_date)' `c(current_time)'","' _n
file write f `" "seed": 42,"' _n
file write f `" "n_obs": `=e(N)',"' _n
file write f `" "estimand": "ATT","' _n
file write f `" "estimator": "`e(cmd)'","' _n
file write f `" "estimate": `b_hat',"' _n
file write f `" "se_cluster": `se',"' _n
file write f `" "ci95_lo": `lo',"' _n
file write f `" "ci95_hi": `hi',"' _n
file write f `" "pre_registration": "strategy.do","' _n
file write f `" "data_contract": "artifacts/data_contract.json","' _n
file write f `" "sample_log": "artifacts/sample_construction.json","' _n
file write f `" "paper_bundle": "tables/table2_main.tex"' _n
file write f "}" _n
file close f
論文の PDF とともに artifacts/result.json をコミットします。査読者が make clean && do main.do を実行すれば、ビット単位で同一のこの JSON を再現できる必要があります。
§A — 疫学/公衆衛生モード
ユーザーの表現からモード A(ターゲットトライアル・エミュレーション/IPTW/TMLE/MR/STROBE/疫学/公衆衛生/RWE/コホート)が示される場合も、8 つのステップは引き続き適用されます。ただしステップ 5 では、OLS と固定効果のスタックを二重に頑健な推定 + 生存時間分析 + MR の 3 点セットに置き換え、成果物は STROBE/TRIPOD-AI の慣例に従います。ステップ 1–4(クリーニング、構築、表 1、診断)とステップ 8(表/図のエクスポート)は、デフォルトモードと同一です。
コマンド構成(デフォルトの Stata スタックに追加でインストール):
ssc install eltmle // TMLE for binary outcome
ssc install mrrobust // Mendelian randomization (IVW / Egger / weighted median)
ssc install mregger // alternative MR-Egger implementation
ssc install mrpresso // outlier-robust MR
ssc install evalue // E-value sensitivity (Linden-Mathur)
ssc install strmst2 // RMST contrast for survival
ssc install gformula // parametric g-formula (time-varying)
* `teffects ipw / ipwra / aipw` are native to Stata 13+; no install needed.
A.0 コホート構築 + ターゲットトライアルのプロトコル
データに触れる前にプロトコルを作成してください。protocol.do として保存し、論文内で引用します。
*--- protocol.do — target-trial emulation skeleton ---
* eligibility: age 40-75, no prior MI, ascertained at t0
* treatment: A=1 statin initiation; A=0 no initiation
* assignment: emulated random at t0 via IPTW on baseline covariates
* outcome: incident MI within 5 years
* estimand: ITT ATE on risk difference + hazard ratio
use raw/cohort.dta, clear
keep if inrange(age, 40, 75) & prior_MI == 0
gen t0 = cond(missing(statin_initiation_date), enrollment_date, statin_initiation_date)
gen event_5y = (MI_date - t0 <= 365 * 5) & !missing(MI_date)
gen time_at_risk = min(censor_date - t0, 365 * 5)
stset time_at_risk, failure(event_5y)
A.1 曝露別の表1(デフォルトモードのステップ3と同一)
ステップ3と同じ balancetable / asdoc tabstat を使用し、by(A) を指定します。未測定交絡に対する E 値は脚注に記載します。
balancetable A age edu smoke bmi ldl sbp using tables/tableA1_strobe.tex, ///
replace ctitles("Untreated" "Treated" "Diff (SE)") pvalues
A.2 DAG + 傾向スコアのオーバーラップ(ポジティビティの確認)
* Estimate PS via logit
logit A age edu smoke bmi ldl sbp
predict ps, pr
* Overlap density (positivity)
twoway (kdensity ps if A == 0) (kdensity ps if A == 1), ///
legend(order(1 "A=0" 2 "A=1")) xtitle("Propensity score")
graph export figures/figA2_ps_overlap.pdf, replace
* Love plot — pre vs post-IPTW SMDs
teffects ipw (event_5y) (A age edu smoke bmi ldl sbp)
tebalance summarize
tebalance density ps
graph export figures/figA2_love.pdf, replace
A.3 IPTW + g-formula + TMLE の二重ロバストな3手法(ステップ5の差し替え)
疫学における「AER 表2」です。3行の表で、各行に { teffects ipw による IPTW-MSM、teffects aipw による IPWRA / AIPW、eltmle による TMLE } のいずれかを示し、読者が二重ロバストな手法間で結果が一致することを確認できるようにします。
* IPTW-MSM (marginal effect on risk difference)
eststo m_iptw: teffects ipw (event_5y) (A age edu smoke bmi ldl sbp), atet
* AIPW (doubly robust ATE)
eststo m_aipw: teffects aipw (event_5y age edu smoke bmi ldl sbp) ///
(A age edu smoke bmi ldl sbp)
* IPWRA — alternative DR estimator
eststo m_ipwra: teffects ipwra (event_5y age edu smoke bmi ldl sbp) ///
(A age edu smoke bmi ldl sbp)
* TMLE via eltmle (uses SuperLearner under the hood)
preserve
eltmle event_5y A age edu smoke bmi ldl sbp, tmle
restore
* Stack the triplet
esttab m_iptw m_aipw m_ipwra using tables/tableA3_dr_triplet.tex, ///
replace b(3) se(3) star(* 0.10 ** 0.05 *** 0.01) ///
mtitles("IPTW" "AIPW" "IPWRA") ///
title("Doubly-robust risk-difference triplet")
A.4 生存アウトカム — KM / Cox / AFT / RMST
* KM by treatment (already stset above)
sts graph, by(A) ci risktable
graph export figures/figA4_km.pdf, replace
* Cox HR (covariate-adjusted)
stcox A age edu smoke bmi ldl sbp
estimates store m_cox
* HR + 95% CI for A:
matrix b = e(b); matrix V = e(V)
local HR = exp(b[1, "A"])
local lo = exp(b[1, "A"] - 1.96*sqrt(V["A","A"]))
local hi = exp(b[1, "A"] + 1.96*sqrt(V["A","A"]))
display "HR = " %5.3f `HR' " 95% CI [" %5.3f `lo' ", " %5.3f `hi' "]"
* AFT (Weibull) for time-ratio interpretation
streg A age edu smoke bmi ldl sbp, distribution(weibull) time
* RMST contrast at t = 5 years
strmst2 A, tau(1825) covariates(age edu smoke bmi ldl sbp)
A.5 メンデルランダム化(IVW / Egger / 加重中央値の3手法)
* Two-sample MR with pre-extracted instrument betas/SEs
* (BX, BXSE, BY, BYSE in long format, one row per SNP)
mrrobust, beta_outcome(by) se_outcome(byse) beta_exposure(bx) se_exposure(bxse)
mregger by bx [aw=1/byse^2], gxse(bxse)
mrmedian by bx, weighted gxse(bxse) gyse(byse)
* Outlier-robust + heterogeneity sensitivity
mrpresso by bx, gxse(bxse) gyse(byse) outlier distortion seed(1) niter(1000)
* Stack the triplet
esttab using tables/tableA5_mr_triplet.tex, ///
replace mtitles("IVW" "MR-Egger" "Weighted median") ///
title("Mendelian randomization triplet")
A.6 ロバスト性 — E 値 / 境界値 / 主層別化
* E-value (Linden-Mathur Stata implementation) — required strength of unmeasured confounding
evalue rr, est(1.45) lcl(1.10) ucl(1.91)
A.7 STROBE / TRIPOD-AI 報告チェックリスト
replication/strobe_checklist.do(または .md)として保存し、投稿前にチェックします。
[ ] Eligibility criteria + dates (target-trial protocol)
[ ] Adjustment set with DAG justification (A.2)
[ ] Positivity / overlap diagnostic (A.2)
[ ] Doubly-robust triplet (IPTW + AIPW + TMLE) (A.3)
[ ] Risk difference + hazard ratio + RMST (A.3, A.4)
[ ] E-value for unmeasured confounding (A.6)
[ ] Loss-to-follow-up rate + censoring assumption (A.0)
[ ] Pre-registered protocol or analysis plan (A.0)
§B — ML 因果推論モード
ユーザーの文言でモードB(DML / メタラーナー / 因果フォレスト / CATE / ポリシー学習 / 因果機械学習)が指定されている場合、パイプラインではデフォルトモードのステップ1〜4とステップ8を維持し、ステップ5を ML 推定器スタックに差し替え、ステップ7とステップ8の間に CATE 分布 + ポリシー価値レイヤーを追加します。
ネイティブ機能と Python の呼び出しに関する説明:Stata 17 以降には、DML と因果フォレスト向けの ML 因果推論コマンドが標準搭載されています。ニューラル因果推論(Dragonnet / TARNet / CEVAE)、コンフォーマル因果推論、公平性監査では、Stata 18 の
python:ブロックを介して Python を呼び出します。各ステップでその旨を明示します。
コマンド構成(デフォルトの Stata スタックに追加してインストールします):
ssc install ddml // double machine learning (Ahrens-Hansen-Schaffer-Wiemann)
ssc install pdslasso // post-double-selection lasso for high-dim controls
ssc install ivlasso // IV variant of pdslasso
ssc install crforest // causal forest (Athey-Tibshirani-Wager) for Stata
ssc install lassopack // covariate selection helpers
* For BART / BCF / Dragonnet / conformal: shell out to Python via `python:` block
* (Stata 18 ships first-class Python integration)
B.0 訓練/ホールドアウト分割 + ナイサンスーパーラーナー
DML / TMLE / 因果フォレストは、ナイサンス学習器(アウトカム回帰 Q(X,A) = E[Y|X,A] および傾向スコア g(A|X) = Pr(A=1|X))が n^(-1/4) より速く収束する場合に二重ロバストです。交差検証のもとで GBM / RF / Lasso / NN をスタックするには、pystacked(Stata 18 + Python 呼び出し)を使用します。これは StatsPAI の SuperLearner に相当する Stata の手法です。
set seed 42
gen u = runiform()
gen byte holdout = u > 0.7
* pystacked — installed via `python: import pystacked` (requires Stata 18 + Python ≥ 3.8)
ssc install pystacked, replace
* The standard nuisance pair (will be reused inside ddml below):
* ml_g = outcome model pystacked Y X*, type(reg) methods(ols rf gradboost lassocv)
* ml_m = propensity model pystacked D X*, type(class) methods(logit rf gradboost)
* For TMLE-style binary-outcome workflows, use -eltmle- which already wraps SL.
* Standalone holdout is needed for the OFF-policy evaluation in B.4 — DML / GRF
* handle their own cross-fitting internally and don't need a manual split.
B.1 DAG / 推定対象の宣言(LLM による支援は任意)
* Causal discovery is thin in Stata — call out to Python's causal-learn:
python:
import pandas as pd
from causallearn.search.ConstraintBased.PC import pc
from sfi import Data
df = pd.DataFrame({v: Data.get(v) for v in ["A","Y","X1","X2","X3","X4"]})
cg = pc(df.to_numpy())
cg.draw_pydot_graph(labels=list(df.columns)).write_pdf("figures/figB1_dag.pdf")
end
B.2 推定器スタック — DML · メタラーナー · 因果フォレスト(ステップ5の差し替え)
ML 因果推論における「AER 表2」です。同じ (Y, A, X) データに対して、各列に異なる推定器ファミリーを示す比較表です。読者は、DML(PLR)、DML(インタラクティブ)、因果フォレストがすべて ATE について同じ結果を示すか(あるいは異なる結果を示すか)を確認できます。
*--- 1. DML — partially linear regression ---
ddml init partial, kfolds(5) reps(5)
ddml E[Y|X]: reg Y X1 X2 X3 X4
ddml E[Y|X]: pystacked Y X1 X2 X3 X4, type(reg) methods(rf gradboost lassocv)
ddml E[D|X]: reg A X1 X2 X3 X4
ddml E[D|X]: pystacked A X1 X2 X3 X4, type(reg) methods(rf gradboost lassocv)
ddml crossfit
ddml estimate, robust
eststo m_dml_plr
*--- 2. DML — interactive (heterogeneous treatment effects) ---
ddml init interactive, kfolds(5) reps(5)
ddml E[Y|X,D]: pystacked Y X1 X2 X3 X4, type(reg) methods(rf gradboost)
ddml E[D|X]: pystacked A X1 X2 X3 X4, type(class) methods(rf gradboost logit)
ddml crossfit
ddml estimate, atet
eststo m_dml_atet
*--- 3. Causal forest — non-parametric CATE ---
crforest Y A X1 X2 X3 X4, ntrees(2000) honesty
predict cate, te
eststo m_cf
*--- 4. (Optional) Neural causal (Dragonnet / TARNet) — Python callout ---
* Stata has no native neural-causal estimator; shell out to econml / causalml:
python:
import numpy as np, pandas as pd
from sfi import Data
from econml.dr import DRLearner
from econml.metalearners import XLearner
from sklearn.ensemble import GradientBoostingRegressor, GradientBoostingClassifier
df = pd.DataFrame({v: Data.get(v) for v in ["Y","A","X1","X2","X3","X4"]})
X = df[["X1","X2","X3","X4"]].values; T = df["A"].values; Y = df["Y"].values
dr = DRLearner(model_propensity=GradientBoostingClassifier(),
model_regression=GradientBoostingRegressor(),
model_final=GradientBoostingRegressor()).fit(Y, T, X=X)
ate, lo, hi = dr.ate(X), *dr.ate_interval(X)
Data.addVarFloat("cate_dr"); Data.store("cate_dr", range(len(df)), dr.effect(X))
end
*--- 5. (Optional) Bayesian Causal Forest (BCF) — R callout ---
* Use the bcf R package via -shell Rscript- to fit the full posterior over CATE.
* The R script writes posterior_summary.csv; we import it back as a frame:
* shell Rscript scripts/bcf.R
* import delimited posterior_summary.csv, clear case(preserve)
*--- 6. Stack the horse-race ---
esttab m_dml_plr m_dml_atet m_cf using tables/tableB2_ml_horserace.tex, ///
replace b(4) se(4) star(* 0.10 ** 0.05 *** 0.01) ///
mtitles("DML (PLR)" "DML (ATET)" "Causal forest") ///
stats(N, labels("N")) ///
title("ML causal horse-race on \$(Y, A, X)\$") ///
addnotes("DR-Learner / Dragonnet / BCF columns added via Python/R callouts when relevant.")
B.3 CATE 分布 + サブグループ CATE プロット(ステップ7の拡張)
* CATE histogram from causal forest
histogram cate, frequency normal xtitle("CATE") xline(0)
graph export figures/figB3_cate_hist.pdf, replace
* CATE by quartile of a covariate
xtile age_q = X1, n(4)
collapse (mean) cate, by(age_q)
graph bar (asis) cate, over(age_q) ytitle("Mean CATE")
graph export figures/figB3_cate_by_age_q.pdf, replace
B.4 ポリシー学習 + オフポリシー評価
* Stata's native policy-tree support is via crforest; for honest depth-3 trees,
* call out to R's policytree from within Stata:
shell Rscript scripts/policy_tree.R // saves policy_pred.csv
import delimited using policy_pred.csv, clear case(preserve)
* DR off-policy evaluation on holdout
keep if holdout
gen DR_match = (policy_pred == A) * Y - (policy_pred != A) * Y
summarize DR_match
display "DR policy value (holdout): " r(mean)
B.5 不確実性(コンフォーマル因果推論)+ 公平性 + 感度分析
python:
# Conformal prediction interval around CATE — distribution-free coverage guarantee
import numpy as np
from sfi import Data
from sklearn.ensemble import GradientBoostingRegressor
from mapie.regression import MapieRegressor
df = ... # same DataFrame as B.1
mapie = MapieRegressor(estimator=GradientBoostingRegressor(), method="plus", cv=10)
# fit on training CATE, predict 90% PI on holdout
end
* Fairness audit — disparate impact (compute via teffects diff across sensitive groups)
foreach g in 0 1 {
quietly mean cate if sensitive_attr == `g'
matrix b = e(b)
display "Mean CATE in group `g': " b[1, 1]
}
B.6 ML 因果推論固有の報告チェックリスト
replication/ml_causal_checklist.md として保存します。
[ ] Nuisance learners listed (Q model, g model, hyperparameters, CV folds)
[ ] Cross-fitting / sample-splitting documented (ddml kfolds(K) reps(R))
[ ] Overlap / propensity diagnostics (B.0 + A.2-style overlap plot)
[ ] CATE summary (mean, SD, quartiles) + heterogeneity p-value (crforest test)
[ ] Policy value with confidence interval (B.4)
[ ] Conformal coverage rate on holdout (B.5)
[ ] Fairness gaps across sensitive attributes (B.5)
[ ] DAG / adjustment set + sensitivity to unmeasured confounding (E-value or Manski bounds)
ライブラリ/コマンド早見表
| 手順 | タスク | 推奨コマンド | 代替手段 |
|---|---|---|---|
| 1 | インポート | use / import excel / import delimited / import sas / import spss | usespss / infile |
| 1 | 欠損値 | misstable summarize / mdesc | missings report |
| 1 | マージ | merge m:1 ... assert(match using) | — |
| 1 | パネル | xtset / xtdescribe | 純粋な時系列には tsset |
| 2 | ウィンザー化 | winsor2 | summ, detail + replace で手動処理 |
| 2 | ラグ/リード/差分 | L. / F. / D.(xtset が必要) | bys id (t): gen lx = x[_n-1] |
| 3 | 表1 | tabstat + balancetable + asdoc sum | 手動ループ |
| 3 | 相関 | pwcorr, sig star(.05) | corr |
| 4 | 不均一分散 | estat hettest / estat imtest, white | — |
| 4 | パネルの系列相関 | xtserial / xttest3 | — |
| 4 | 定常性 | dfuller / kpss / pperron / xtunitroot | — |
| 4 | ハウスマン検定 | hausman fe re, sigmamore | — |
| 5 | OLS/パネル固定効果 | reghdfe | areg / xtreg, fe |
| 5 | IV | ivreg2 / ivreghdfe | ivregress 2sls |
| 5 | DID — 2×2 | c.treated#c.post を使った reg / reghdfe | — |
| 5 | DID — CS | csdid | — |
| 5 | DID — SA | eventstudyinteract | — |
| 5 | DID — 補完法 | did_imputation | did_multiplegt_dyn |
| 5 | DID — SDID | sdid | — |
| 5 | RD | rdrobust / rddensity / rdplot | 複数のカットオフには rdmc |
| 5 | 合成コントロール | synth / synth_runner | — |
| 5 | PSM | psmatch2 / teffects psmatch | — |
| 5 | IPW/AIPW | teffects ipw / teffects ipwra / teffects aipw | — |
| 5 | エントロピー・バランシング | ebalance | — |
| 5 | カウントデータ+固定効果 | ppmlhdfe | poisson / nbreg |
| 5 | ヘックマン | heckman | 手動の2段階法 |
| 5 | 分位点 | qreg / sqreg | bsqreg |
| 6 | ワイルド・クラスター・ブートストラップ | boottest | bootstrap, cluster() |
| 6 | ランダム化推論 | ritest | permute |
| 6 | 多重検定 | rwolf | wyoung |
| 6 | TWFE 診断 | bacondecomp | — |
| 6 | PT 感度分析 | honestdid | — |
| 6 | Oster δ* | psacalc delta | 手動計算式 |
| 7 | 交互作用の限界効果 | margins + marginsplot | — |
| 7 | 媒介分析 | medsem / khb | 手動の Baron–Kenny 法 |
| 7 | SEM/パス解析 | sem / gsem | — |
| 8 | 回帰表 | esttab(estout から) | outreg2 / xtable |
| 8 | 係数プロット/イベントスタディ | coefplot | marginsplot |
| 8 | ビン散布図 | binscatter | 手動の twoway |
| 8 | RD プロット | rdplot | — |
よくある間違い(および代わりに行うこと)
| 間違い | 正しい方法 |
|---|---|
FE を指定せず、パネルデータに reg y x1 x2 を使用する | reghdfe y x1 x2, absorb(unit time) vce(cluster unit) |
| クラスター化データにデフォルトの iid 標準誤差を使用する | vce(cluster id) を使用します。クラスター数が 50 未満の場合は boottest を使用します |
段階的な導入に TWFE(処置ダミーを使った reghdfe)を使用する | csdid/eventstudyinteract/did_imputation を使用します |
大規模パネル(ユニット数が 10k 超)で xtreg, fe を使用する | reghdfe に切り替えます。より高速で、多次元 FE と多方向クラスター化に対応します |
assert() を指定せずに merge を使用する | 必ず assert(match using master) などを指定します |
事前に xtset せず L.x でラグを生成する | 時系列操作の前に xtset id time を実行します |
estat firststage を実行せずに ivregress を使用する | 弱 IV の診断には ivreg2 を推奨します。CD、KP、AR を自動的に報告します |
| RD で帯域幅を 1 つだけ使用する | rdrobust はデフォルトで MSE 最適値と感度分析を報告します。また、rdbwselect を表示し、帯域幅を半分/2 倍にします |
バランスを確認せずに psmatch2 を使用する | pstest, both を使用して、マッチング前後の SMD を報告します。目標は 10% 未満です |
logit の係数をそのまま解釈する | 必ず margins, dydx(*) を実行します。これが解釈可能な値です |
estimates のみを報告し、手作業でコピー&ペーストする | esttab/outreg2 を使えば、LaTeX/Word/RTF に自動出力できます |
| 要点となる係数だけを報告する(Table 2 がない) | 必ず 複数列の M1→M6 メインテーブルを用意します。これは経済学論文の中心となるものであり、要旨の一文ではありません |
| 図を含まない係数表を作成する | 経済学の結果には、少なくとも F1 のトレンド図、F2 のイベントスタディ図、F3 の係数プロット、F4 の感度分析が必要です。Default Output Spec を参照してください |
graph save(.gph のみ)でグラフを保存する | .pdf/.png にも graph export ..., replace でエクスポートします |
| セッションを記録しない | do-file の先頭で log using main.log, replace を実行します |
回帰内で c.x##c.x を使わずに gen x2 = x^2 を使用する | 因子変数表記は margins と相性が良いです |
.do-file の基本構成
* ============================================================
* main.do — reproducible 8-step pipeline
* ============================================================
version 17
clear all
set more off
capture log close
log using "logs/main.log", replace text
cd "/path/to/project"
* 1. Clean -----------------------------------------------------
do "code/01_clean.do" // produces data/analysis.dta
* 2. Transform -------------------------------------------------
do "code/02_transform.do" // adds engineered vars
* 3. Describe --------------------------------------------------
do "code/03_describe.do" // writes tables/table1_*, figures/*_trend.pdf
* 4. Diagnose --------------------------------------------------
do "code/04_diagnose.do" // writes logs/diagnostics.log
* 5. Model -----------------------------------------------------
do "code/05_model.do" // saves e() for m1–m6 via eststo
* 6. Robustify -------------------------------------------------
do "code/06_robust.do"
* 7. Further ---------------------------------------------------
do "code/07_further.do"
* 8. Export ----------------------------------------------------
do "code/08_tables_figures.do" // writes tables/*.tex, figures/*.pdf
log close
すべての .do ファイルは data/analysis.dta を読み込み、出力を tables/ または figures/ に書き込み、ログを保存します。make clean && do main.do を実行すれば、元データから論文全体を再生成できます。
回帰表(esttab)クックブック(一ページのレシピ索引)
eststo と esttab は、AER 論文のあらゆる複数回帰表の基盤となる基本機能です。上記の 8 つのパターンは、次のように対応します。
| パターン | 列間で変化するもの | 手順 |
|---|---|---|
| A. 制御変数の段階的追加 | 共変量のセット/FE の深さ | 5.A — Table 2 |
| B. 識別戦略の比較 | 識別戦略(OLS/IV/DID/PSM/EB) | 5.B — Table 2-bis |
| C. 複数の結果変数 | 従属変数 Y | 5.C — Table 2-ter |
| D. Panel A/B の積み上げ | 対象期間/サンプル(パネル行 × 仕様列) | 5.D — Table 2-quater |
| E. IV 報告の 3 点セット | 第 1 段階/縮約形/2SLS | 5.E — Table 2-quinto |
| F. 因果推論オーケストレーター | 1 列、完全な診断(csdid/synth_runner/teffects) | 5.F |
| G. サブグループ表 | サブサンプル(全体/女性/男性/Q1…Q4) | 7.b — Table 3 |
| H. ロバストネス検証のマスター表 | すべてのロバストネス検証を積み上げ | 6.k — Table A1 |
AER のスタイルに合わせた esttab のデフォルト設定:
esttab m1 ... mN using "tables/tableN.tex", ///
replace ///
se star(* 0.10 ** 0.05 *** 0.01) /// AER stars convention
label booktabs ///
mtitles("(1)" "(2)" ...) /// column labels
stats(N r2 r2_a, labels("N" "R²" "Adj. R²")) ///
addnotes("Cluster-robust SE in parentheses." ///
"* p<0.10, ** p<0.05, *** p<0.01.")
* Word version: same call with .rtf extension.
* For multi-panel paper bundles, chain esttab with `, append` (see 5.D / 8.5.4).
図表ファクトリー(Stata の標準 AER 図表 12 種)
| # | 図表 | Stata コマンド | セクション |
|---|---|---|---|
| 1a | 生のトレンド(DID 図 1) | collapse (mean) y, by(year treat) → twoway line | §1(ステップ 3.e) |
| 1b | 処置導入のヒートマップ | heatplot first_treat unit, color(...) | §1 |
| 2a | イベントスタディ係数 | eventstudyinteract → coefplot, keep(rel_d*) | §3(ステップ 3.5.1) |
| 2a' | Bacon 重み | bacondecomp y treat, ddetail → 組み込みグラフ | §3 |
| 2a'' | CS-DID 動学的効果 | csdid → csdid_plot | §3 |
| 2b | 第一段階の散布図 | binscatter D Z, controls(X) | §3(ステップ 3.5.2) |
| 2c | RD の標準プロット | rdplot Y X, c(0) | §3(ステップ 3.5.3) |
| 2c' | McCrary 密度 | rddensity X, c(0) plot | §3 |
| 2d | マッチングのラブプロット | pstest X, both graph(psmatch2 の実行後) | §3(ステップ 3.5.4) |
| 2e | SCM の推移 | synth y X, trunit() trperiod() fig · sdid グラフ | §3(ステップ 3.5.5) |
| 3 | 主な仕様の係数プロット | coefplot m1...m6, keep(D) | §4(ステップ 8.f) |
| 4a | 用量反応 | xtile dose10 = D, nq(10) → margins i.dose10 → marginsplot | §5(ステップ 7.g) |
| 4b | サブグループ別マージン | margins, dydx(D) at(group=(0 1)) → marginsplot | §5 |
| 5 | 仕様曲線 | 手書きの仕様ループ → twoway rcap(6.l を参照) | §7 |
| 6 | 感度分析ダッシュボード | honestdid, coefplot · psacalc plot · evalue | §7(ステップ 6.m) |
| 7 | 最終的な主図 | 推定量に応じたもの(csdid_plot、synth fig、rdplot) | §8 |
Stata の図表はすべて、LaTeX 用の
.png ≥ 300 dpiの両方でエクスポートします。一貫したスタイルにするため、master.doの先頭で一度set scheme s2color(またはschemepackのwhite_tableau)を使用します。
手法カタログ
古典的 OLS/パネル
reg log_wage training age edu, vce(cluster firm_id) // OLS
areg log_wage training age edu, absorb(industry) vce(cluster firm_id) // OLS + 1 FE
xtreg log_wage training age edu, fe // panel FE
xtreg log_wage training age edu, re // panel RE (Hausman)
reghdfe log_wage training age edu, absorb(worker_id year) vce(cluster firm_id) // HD FE workhorse
reghdfe log_wage training, absorb(worker_id year) vce(cluster firm_id year) // 2-way cluster
ppmlhdfe count training, absorb(firm_id year) cluster(firm_id) // Poisson + FE
heckman log_wage training, select(in_lf = age edu marital kids) // Heckman selection
qreg log_wage training age, quantile(0.5) // quantile reg
sqreg log_wage training age, quantile(0.1 0.25 0.5 0.75 0.9) reps(500)
差の差法
* 2×2
reghdfe log_wage c.treat#c.post, absorb(worker_id year) vce(cluster worker_id)
* Staggered — modern stack
csdid log_wage age edu, ivar(worker_id) time(year) gvar(first_treat) method(dripw) agg(group)
eventstudyinteract log_wage rel_d*, cohort(first_treat) control_cohort(never_treated) absorb(worker_id year) vce(cluster worker_id)
did_imputation log_wage worker_id year first_treat, allhorizons pretrend(5)
did_multiplegt_dyn log_wage worker_id year training, effects(5) placebo(3)
sdid log_wage worker_id year training, vce(bootstrap) graph
* Diagnostics + sensitivity
bacondecomp log_wage training, ddetail // TWFE diagnostic
honestdid, pre(rel_d1-rel_d3) post(rel_d5-rel_d9) mvec(0(0.1)0.5) // PT sensitivity
操作変数法/2SLS
ivregress 2sls log_wage age edu (training = Z), vce(cluster firm_id) // baseline
ivreg2 log_wage age edu (training = Z), cluster(firm_id) first endog(training) // workhorse: full diagnostics
ivreghdfe log_wage age (training = Z), absorb(industry year) cluster(firm_id) first
* Weak-IV diagnostics
estat firststage // (after ivregress)
* ivreg2 reports CD / KP / AR automatically.
回帰不連続デザイン
rdrobust outcome running_var, c(0) kernel(triangular) bwselect(mserd) // Sharp RD (CCT)
rdrobust outcome running_var, c(0) fuzzy(treatment) // Fuzzy RD
rddensity running_var, c(0) plot // McCrary density
rdmc outcome running_var, cutoffs(0 5 10) // multi-cutoff
rdplot outcome running_var, c(0)
マッチング/再重み付け
psmatch2 training age edu tenure, out(log_wage) n(1) common // PSM (canonical)
teffects psmatch (log_wage) (training age edu tenure), atet // PSM (modern)
teffects ipw (log_wage) (training age edu tenure), atet // IPW
teffects ipwra (log_wage age edu tenure) (training age edu tenure) // IPWRA
teffects aipw (log_wage age edu tenure) (training age edu tenure) // AIPW (DR)
ebalance training age edu tenure // entropy balancing
合成コントロール法
synth log_wage age edu, trunit(1) trperiod(2015) fig keep(synth.dta, replace)
synth_runner log_wage age edu, trunit(1) trperiod(2015) gen_vars // + 50 placebos
sdid log_wage worker_id year training, vce(bootstrap) graph
ML 因果推論(モード B — パイプライン全体については §B を参照)
ddml init partial, kfolds(5) reps(5) // DML setup
ddml E[Y|X]: pystacked Y X*, type(reg) methods(rf gradboost lassocv)
ddml E[D|X]: pystacked D X*, type(reg) methods(rf gradboost lassocv)
ddml crossfit
ddml estimate, robust
crforest log_wage training age edu, ntrees(2000) honesty // causal forest
predict cate, te
pdslasso log_wage training (X1-X100), cluster(firm_id) partial // post-double-selection
ロバストネス、感度分析、推論
boottest training, cluster(state) reps(9999) seed(42) // wild cluster bootstrap
ritest training _b[training], reps(1000) seed(0): reghdfe ... // randomization inf.
rwolf y1 y2 y3, indepvar(training) controls(X) reps(500) ... // Romano-Wolf MTC
psacalc delta training, mcontrol(X) rmax(1.3) // Oster δ
honestdid, pre(...) post(...) mvec(0(0.1)0.5) // RR PT sensitivity
evalue rr, est(1.45) lcl(1.10) ucl(1.91) // E-value
xtcsd, pesaran abs // cross-sec dependence
生存分析/疫学(モード A — §A を参照)
stset time, failure(event)
sts graph, by(A) ci risktable // Kaplan-Meier
stcox A age edu // Cox
streg A age edu, distribution(weibull) time // AFT
strmst2 A, tau(1825) covariates(age edu) // RMST contrast
gformula ... // parametric g-formula
eltmle event A age edu, tmle // TMLE for binary outcome
mrrobust, beta_outcome(by) se_outcome(byse) beta_exposure(bx) se_exposure(bxse) // MR-IVW
mregger by bx [aw=1/byse^2], gxse(bxse) // MR-Egger
他のスキルに引き継ぐ場合
- エージェントネイティブな単一インポートの Python ワークフロー(
import statspai as sp)→00-StatsPAI_skill。 - Python の従来型スタックを明示的に使用する場合 →
00.1-Full-empirical-analysis-skill。 - Mixtape 形式のクロス言語コードテンプレート(Python/R/Stata の並列表記)→
10-Jill0099-causal-inference-mixtape。 - Stata 構文リファレンス(コマンドカタログ全体、Mata など)→
32-dylantmoore-stata-skill。 - 会計研究向け Stata →
18-jusi-aalto-stata-accounting-research。 - 分析完了後の論文執筆 → このリポジトリ内の執筆向けスキル(
04-*-scientific-writer、08-*-web-latexなど)。
このスキルの対象範囲はステップ 8 までです — 仕上げ済みの .tex テーブルと .pdf 図表が対象です。論文執筆は対象外です。
ステップ 8.5 — 原稿への引き継ぎ(終了時の契約)
このスキルの担当範囲は、引き続きステップ 8 までです。ただし、「終了」が「行き止まり」を意味するべきではありません。 執筆段階には、ばらばらのファイルのフォルダーではなく、機械可読な契約が必要です。 作業を終える前に、表や図と同じ場所に 2 つの成果物を出力してください。
1. exhibits_index.md — 番号付き展示資料ごとに 1 行:
| 展示資料 | ファイル | 裏付ける主張 | 作成元 |
|---|---|---|---|
| 表 2 | tables/table2_main.{tex,docx,xlsx} | 政策が対数出力に及ぼす主な効果 | analysis.do §baseline |
| 図 2 | figures/fig2_event_study.{png,pdf} | 事前トレンドに差がないこと | analysis.do §event-study |
2. results_summary.json — すべての主要推定値をフラットなレコードとして記録:
{"baseline": {"coef": 0.1234, "se": 0.0412, "p": 0.0031, "n": 12345, "spec": "TWFE + region-year FE"}}
両方が必要な理由と、この形式にする理由:
- 原稿段階では、展示資料を再入力した数値ではなく、インクルード指示で引用します。LaTeX では
\input{tables/table2_main}、Markdown では{{ include: table2_main }}を使います。どのファイルがどの主張を裏付けているかを執筆者に伝えるのが、このインデックスです。 - 論文に掲載する数値はすべて、表示精度で結果ファイルまで遡れる必要があります。
results_summary.jsonを使えば、信頼するだけでなく検証可能になります。レンダリング済みの表にしかない係数は、それを引用する本文と照合できません。
次の引き継ぎ先:
- 論文全体 → Word
.docx/ LaTeX、一貫した制作工程 →skills/69-Paper-WorkFlow/。このワークフローはステージ 5〜9(草稿 → 推敲 → AI 生成らしさの低減 → 査読 → 投稿)を統括し、scripts/assemble_manuscript_docx.pyが、本文、上記のすべての展示資料、図、参考文献一覧を 1 つのファイルにまとめて09_submission/main.docxを作成します。その際、これら 2 つの成果物のみを入力として使用します。ステージ 0 で本文の形式を選択してください。提出物が Word の場合は Markdown(Markdown →.docxは高品質ですが、LaTeX →.docxは情報が失われます)、提出先が.texを受け付ける場合は LaTeX を選択します。 - 本文の執筆のみ → このリポジトリの執筆スキル(
04-*-scientific-writer、35-*-academic-writing-skills)。 - LaTeX / Quarto による組版のみ →
08-ndpvt-web-latex-document-skill、60-regisely-superpapers。