F2-smoke-01 — Slope of y on x with firm-clustered uncertainty
Question
Estimate the population linear-projection slope β in y = α + βx + ε for a (synthetic) firm panel, with standard errors that allow arbitrary dependence among observations of the same firm (independence across firms only). This is a descriptive projection coefficient, not a causal effect.
Data and exclusions
data/panel.csv (SHA-256 968410b9…ce5a8): 2000 rows read (n_input_rows), columns firm_id, x, y. No missing, non-finite or duplicate rows; 50 firms with exactly 40 observations each. The single exclusion rule (drop incomplete rows) removed 0 rows (out/exclusions.csv), so n_analysed = 2000 and n_clusters = 50. data_issues is empty. Full audit: out/state/data_audit.md.
Method
OLS of y on x with an intercept (closed form). Baseline uncertainty: conventional homoskedastic OLS standard error (se_ols). Main uncertainty: cluster-robust sandwich variance by firm_id with the CR1 small-sample factor G/(G−1)·(N−1)/(N−K) (Stata/statsmodels default); the 95% CI uses t critical values with G−1 = 49 degrees of freedom (ci_t_critical_df_G_minus_1 = 2.0096). No randomness is used (random_seed = null). Implemented in out/analysis.py; results cross-checked against statsmodels.
Results
- Slope
beta_hat= 0.8051; interceptalpha_hat= 1.4440. - Clustered SE
se_cluster= 0.0731; 95% CI [beta_ci_low,beta_ci_high] = [0.658, 0.952]. - Naïve baseline
se_ols= 0.0241 (baseline CI [baseline_ci_low_ols,baseline_ci_high_ols] = [0.758, 0.852]).
Uncertainty
The clustered SE is about 3.0 times the naïve SE (se_ratio_cluster_over_ols = 3.03). Both the residuals and x contain substantial firm-level components (the share of variance between firm means is 0.53 for residuals, share_between_firm_var_resid, and 0.45 for x, share_between_firm_var_x), so the conventional SE strongly overstates precision. The clustered CI (beta_ci_low, beta_ci_high) is the one to use for inference. It still excludes zero by a wide margin.
Limitations and open issues
- Cluster-robust inference is asymptotic in the number of clusters. 50 balanced clusters is usually enough, but coverage may still be a little below nominal. A wild cluster bootstrap could serve as a robustness check, but the task does not require one.
- OLS uses within- and between-firm variation together. If the firm shock is correlated with x, β is still the population projection slope the task asks for, but it should not be read causally or as a within-firm effect.
- The data are synthetic; no external validity is implied.