Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Expert panel data regression analysis with fixed effects and GMM
.claude/skills/brycewang-stanford-panel-data-analyst/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-02 | ✗→✓ | ▲ Improved | 124% | 0% |
| case-15 | ✗→✓ | ▲ Improved | 109% | 0% |
| case-18 | ✗→✓ | ▲ Improved | 80% | 0% |
| case-01 | ✓→✓ | = Same ✓ | 103% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 71% | 0% |
Perform expert-level panel data regression analysis including fixed effects, random effects, dynamic panel models (Arellano-Bond/Blundell-Bond GMM), and advanced diagnostic tests. This skill covers the full workflow from panel setup through model selection, estimation, and publication-ready reporting.
Panel data -- repeated observations on the same cross-sectional units over time -- is the workhorse of modern empirical economics, finance, political science, and management research. Panel methods exploit both cross-sectional and temporal variation, enabling researchers to control for unobserved heterogeneity that would bias ordinary cross-sectional estimates.
The choice between fixed effects, random effects, and dynamic panel estimators depends on the data structure, the nature of unobserved heterogeneity, and the identifying assumptions the researcher is willing to make. This skill provides a systematic decision framework and implementation in both Stata and R, with emphasis on the diagnostic tests that justify model selection.
Beyond basic FE/RE models, this skill covers the advanced techniques increasingly required by journal reviewers: instrumental variables within panel frameworks, Driscoll-Kraay standard errors for cross-sectional dependence, correlated random effects (Mundlak/Chamberlain), and system GMM for dynamic panels with endogenous regressors.
stata* Stata panel setup xtset firm_id year xtset // Verify panel structure * Check panel balance xtdescribe * Shows: min/max/avg observations per panel, gaps * Summary statistics by panel dimension xtsum revenue profit employees rnd_spending * Reports overall, between, and within variation
stata* Check for gaps in panel xtset firm_id year gen gap = year - l.year if l.year != . tab gap // Should be all 1's for balanced annual panels * Create balanced subsample by firm_id: gen T_i = _N tab T_i keep if T_i == max_T // Keep only units observed in all periods * Attrition analysis gen in_panel = 1 xtset firm_id year tsfill, full replace in_panel = 0 if missing(in_panel) reg in_panel l.revenue l.profit l.size, cluster(firm_id)
stata* Within estimator (entity fixed effects) xtreg profit revenue rnd_spending employees i.year, fe robust estimates store fe_model * Entity and time fixed effects reghdfe profit revenue rnd_spending employees, /// absorb(firm_id year) cluster(firm_id) estimates store twoway_fe * First-differences (alternative to within estimator) reg d.profit d.revenue d.rnd_spending d.employees i.year, /// cluster(firm_id) estimates store fd_model
stata* GLS random effects xtreg profit revenue rnd_spending employees i.year, re robust estimates store re_model
stata* Classic Hausman test xtreg profit revenue rnd_spending employees, fe estimates store fe_haus xtreg profit revenue rnd_spending employees, re estimates store re_haus hausman fe_haus re_haus * Robust Hausman test (preferred with heteroskedasticity) * Mundlak (1978) approach: add group means to RE model foreach var of varlist revenue rnd_spending employees { bysort firm_id: egen m_`var' = mean(`var') } xtreg profit revenue rnd_spending employees /// m_revenue m_rnd_spending m_employees i.year, re cluster(firm_id) test m_revenue m_rnd_spending m_employees * Rejection => FE preferred; failure to reject => RE acceptable
stata* When the lagged dependent variable is a regressor: * y_it = alpha * y_{i,t-1} + X_it * beta + mu_i + epsilon_it * Difference GMM (Arellano & Bond 1991) xtabond profit l.profit revenue rnd_spending employees, /// lags(1) twostep robust artests(2) * Diagnostics * AR(1) should be significant, AR(2) should NOT be significant * Hansen J test of overidentifying restrictions (p > 0.10 desired)
stata* System GMM (Blundell & Bond 1998) * More efficient than difference GMM, especially with persistent series xtabond2 profit l.profit revenue rnd_spending employees i.year, /// gmm(l.profit, lag(2 4) collapse) /// gmm(revenue rnd_spending, lag(2 3) collapse) /// iv(employees i.year) /// twostep robust orthogonal small * Key diagnostics to report: * 1. Number of instruments (should not exceed number of groups) * 2. Hansen J test p-value (> 0.10, but < 0.25 preferred -- not too high) * 3. AR(2) test p-value (> 0.10 for valid instruments) * 4. Difference-in-Hansen test for subset of instruments
| Test | Null Hypothesis | Desired Result | Stata Command | |------|----------------|----------------|---------------| | AR(1) | No first-order autocorrelation | Reject (p < 0.05) | Reported automatically | | AR(2) | No second-order autocorrelation | Fail to reject (p > 0.10) | Reported automatically | | Hansen J | Instruments are valid | Fail to reject (p > 0.10) | Reported automatically | | Diff-in-Hansen | Level instruments valid | Fail to reject (p > 0.10) | Reported automatically | | Instrument count | -- | N_instruments < N_groups | Check output |
stata* Entity-clustered (default choice for firm panels) xtreg profit revenue rnd_spending, fe cluster(firm_id) * Two-way clustering (firm and year) reghdfe profit revenue rnd_spending, /// absorb(firm_id) cluster(firm_id year) * Driscoll-Kraay standard errors (cross-sectional dependence) xtscc profit revenue rnd_spending i.year, fe lag(3) * Newey-West within panels (autocorrelation + heteroskedasticity) xtreg profit revenue rnd_spending, fe xtpcse profit revenue rnd_spending i.firm_id, correlation(ar1)
stata* Test for heteroskedasticity in FE model xtreg profit revenue rnd_spending, fe xttest3 // Modified Wald test (rejects => use robust/cluster SE) * Test for serial correlation xtserial profit revenue rnd_spending * Wooldridge test (rejects => use cluster SE or Newey-West) * Test for cross-sectional dependence xtreg profit revenue rnd_spending, fe xtcsd, pesaran abs * Pesaran CD test (rejects => consider Driscoll-Kraay SE)
stata* Continuous x continuous interaction with FE xtreg profit c.rnd_spending##c.market_share i.year, fe cluster(firm_id) * Visualize marginal effect margins, dydx(rnd_spending) at(market_share=(0(0.1)1)) marginsplot, title("Marginal Effect of R&D by Market Share")
stata* IV with fixed effects (xtivreg) xtivreg profit (rnd_spending = tax_credit regulatory_change) /// employees size i.year, fe first * First-stage F-statistic check * Report Kleibergen-Paap rk Wald F for weak instruments
stata* Mundlak (1978) approach: include within-group means foreach var of varlist revenue rnd_spending employees { bysort firm_id: egen bar_`var' = mean(`var') } xtreg profit revenue rnd_spending employees /// bar_revenue bar_rnd_spending bar_employees /// i.year, re cluster(firm_id) * Coefficients on time-varying vars are equivalent to FE estimates * Coefficients on bar_ vars capture between-unit effects
stata* Comparison table: FE vs RE vs GMM esttab fe_model re_model gmm_model using "tables/panel_comparison.tex", /// b(3) se(3) star(* 0.10 ** 0.05 *** 0.01) /// label title("Panel Regression Results") /// mtitles("Fixed Effects" "Random Effects" "System GMM") /// stats(N N_g r2_w ar2p hansenp, /// labels("Observations" "Firms" "Within R-squared" /// "AR(2) p-value" "Hansen p-value") /// fmt(0 0 3 3 3)) /// addnotes("Clustered standard errors in parentheses." /// "All models include year fixed effects.") /// replace
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-02 | fail→pass | 11,591 | 14,502 | +25% | 1 | 1 | 0% | 2,167 | 4,856 | +124% | 0 | 0 | — |
case-01 | pass→pass | 13,534 | 19,468 | +44% | 1 | 1 | 0% | 2,469 | 5,014 | +103% | 0 | 0 | — |
case-03 | pass→pass | 18,208 | 13,196 | -28% | 1 | 1 | 0% | 2,742 | 4,679 | +71% | 0 | 0 | — |
case-04 | pass→pass | 17,267 | 16,220 | -6% | 1 | 1 | 0% | 2,974 | 5,384 | +81% | 0 | 0 | — |
case-05 | pass→pass | 14,497 | 14,418 | -1% | 1 | 1 | 0% | 2,790 | 5,176 | +86% | 0 | 0 | — |
case-06 | pass→pass | 18,581 | 15,275 | -18% | 1 | 1 | 0% | 2,821 | 5,076 | +80% | 0 | 0 | — |
case-07 | pass→pass | 11,150 | 7,544 | -32% | 1 | 1 | 0% | 1,883 | 3,744 | +99% | 0 | 0 | — |
case-08 | pass→pass | 7,509 | 6,918 | -8% | 1 | 1 | 0% | 1,435 | 3,675 | +156% | 0 | 0 | — |
case-09 | pass→pass | 15,506 | 18,380 | +19% | 1 | 1 | 0% | 2,883 | 5,878 | +104% | 0 | 0 | — |
case-10 | pass→pass | 16,615 | 16,735 | +1% | 1 | 1 | 0% | 2,766 | 5,251 | +90% | 0 | 0 | — |
case-11 | pass→pass | 14,756 | 14,652 | -1% | 1 | 1 | 0% | 2,630 | 4,901 | +86% | 0 | 0 | — |
case-12 | pass→pass | 12,643 | 16,392 | +30% | 1 | 1 | 0% | 2,377 | 5,355 | +125% | 0 | 0 | — |
case-13 | fail→fail | 22,093 | 18,617 | -16% | 1 | 1 | 0% | 3,587 | 5,512 | +54% | 0 | 0 | — |
case-14 | pass→pass | 19,580 | 18,576 | -5% | 1 | 1 | 0% | 3,483 | 5,736 | +65% | 0 | 0 | — |
case-15 | fail→pass | 10,237 | 9,530 | -7% | 1 | 1 | 0% | 2,016 | 4,212 | +109% | 0 | 0 | — |
case-16 | pass→pass | 16,155 | 18,234 | +13% | 1 | 1 | 0% | 2,896 | 5,707 | +97% | 0 | 0 | — |
case-17 | pass→pass | 7,471 | 8,621 | +15% | 1 | 1 | 0% | 1,197 | 3,804 | +218% | 0 | 0 | — |
case-18 | fail→pass | 12,245 | 7,848 | -36% | 1 | 1 | 0% | 2,176 | 3,911 | +80% | 0 | 0 | — |
case-19 | pass→pass | 16,268 | 13,978 | -14% | 1 | 1 | 0% | 2,748 | 4,894 | +78% | 0 | 0 | — |
case-20 | fail→fail | 22,221 | 26,478 | +19% | 1 | 1 | 0% | 3,846 | 6,430 | +67% | 0 | 0 | — |
case-21 | pass→pass | 12,641 | 13,841 | +9% | 1 | 1 | 0% | 2,326 | 4,700 | +102% | 0 | 0 | — |
case-22 | pass→pass | 17,393 | 16,200 | -7% | 1 | 1 | 0% | 3,150 | 5,154 | +64% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +14 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.