F2-dev-01 — Two-way fixed-effects slope with firm-clustered uncertainty
Question
Estimate β in y_it = a_i + g_t + β x_it + u_it, the within-firm, within-year association of y with x. Firm effects a_i and year effects g_t are unrestricted. Inference allows arbitrary dependence of u_it within a firm over time and assumes independence across firms. The data are simulated.
Data and exclusions
data/firm_panel.csv (SHA-256 ae54378f…72e0) has 1200 rows (n_input_rows). It is a balanced panel: 100 firms (n_firms) × 12 years, 2008–2019 (n_years). There are no missing values, no duplicate rows and no duplicate firm–year keys, so data_issues is empty. The exclusion rules (missing values, exact duplicates, conflicting firm–year keys) removed 0 rows, so n_analysed = 1200 (see out/exclusions.csv). Full audit: out/state/data_audit.md.
Method
- Baseline: pooled OLS of y on x with an intercept and no fixed effects (
beta_pooled). - Main estimate: two-way fixed effects estimated by least-squares dummy variables (LSDV), i.e. OLS of y on x plus firm and year dummies, 112 parameters in total (
n_params_lsdv). As a cross-check, the slope from two-way within-demeaning (which is exact because the panel is balanced) matches to within 1e-8 (beta_fe_within_check). se_conventional: the classical homoskedastic OLS standard error from the LSDV regression, with N − K = 1088 degrees of freedom.se_cluster: a cluster-robust sandwich standard error clustered byfirm_id, with the CR1 small-sample factor G/(G−1)·(N−1)/(N−K). Here K counts all 112 LSDV parameters (Stataaregconvention), which is the more conservative choice.- 95% CI:
beta_fe± t(0.975, G−1 = 99) ×se_cluster. The critical value isci_critical_value_t_Gminus1= 1.984. - The method uses no randomness (
random_seed= null).
Results
- Pooled OLS baseline:
beta_pooled= 1.268 (conventional SE 0.028,baseline_se_pooled_conventional). - TWFE estimate:
beta_fe= 0.6045. - The TWFE slope is about half the pooled slope. This pattern fits firm and/or year effects that are positively correlated with x and inflate the naïve estimate. The difference does not by itself identify which effects cause it.
Uncertainty
se_conventional= 0.0326;se_cluster= 0.0471. The ratio is 1.44 (se_ratio_cluster_to_conventional), which fits positive within-firm dependence of the residuals and x over time. The conventional SE therefore understates uncertainty.- 95% firm-clustered CI: [
beta_ci_low,beta_ci_high] = [0.511, 0.698]. It excludes 0 and also excludes the pooled estimate 1.268. - Sensitivity to the degrees-of-freedom convention: if the firm dummies are not counted in K, because they are nested within clusters (
xtreg, feconvention), the clustered SE is 0.0451 (se_cluster_sensitivity_firmFE_not_counted). With no small-sample correction (CR0) it is 0.0446 (se_cluster_CR0_no_correction). The conclusions do not change.
Limitations and open issues
- β is a causal effect only under strict exogeneity of x given a_i and g_t; with simulated data, β is simply the parameter of the stated model.
- Cluster-robust inference relies on asymptotics in the number of firms. G = 100 is a reasonable number of clusters, but the SE depends slightly on the small-sample convention (see Uncertainty). I report the conservative LSDV-K version as the primary result.
- I found no data problems, and the task was completed in full (
feasibility= "complete").