固定效应回归与含虚拟变量混合OLS的结果差异问题咨询
Hey there! Let's break down your panel regression confusion with the plm package. It’s super frustrating when two models you think should be identical spit out different results—plus the error messages make it even trickier. Let’s unpack this step by step.
You mentioned Model 2 and Model 3 should produce identical results, but they don’t, and you’re getting errors during execution. From your partial code snippet:
Model1 <- plm((op_margin) ~ pur_dum + log(firm_age) + log(fleet_end) + factor(year) + factor(country), data= dt.airline, index=c('code','year'), model = ...)
I’m guessing your Model 2 and 3 are variations of this—maybe one uses manually added factor(year)/factor(country) while the other relies on plm’s built-in fixed effect options (like effect = "twoways"). Let’s dive into why these might not match, and what’s causing the errors.
1. You’re Comparing Apples to Oranges (Model Setup Differences)
The biggest culprit here is often unintended differences in model specification:
- If Model 2 uses a pooled OLS model with manual time/country dummies, but Model 3 uses a within (fixed effect) model with two-way effects (firm + year), these are fundamentally different models. The fixed effect model absorbs firm-specific unobserved heterogeneity, while the pooled model doesn’t—so results will never line up.
- Even if you intended both to include firm + time + country effects: if
countryis a time-invariant variable (i.e., each firm stays in the same country for the entire sample), addingfactor(country)to a firm fixed effect model will cause multicollinearity. The firm fixed effect already absorbs all time-invariant firm attributes (like country), so thefactor(country)coefficients can’t be estimated (they’ll show up asNAor get dropped entirely), which throws off your results and causes errors.
2. Panel Data Structure Issues
- Unbalanced Panels: If your dataset isn’t balanced (some firms are missing years),
plm’s built-in fixed effect handling might drop observations differently than when you manually add dummies. For example,plmmight exclude firms with too few observations, while manual dummies just leave those rows in with missing values for some dummies. - Incorrect Indexing: Double-check that your
index=c('code','year')correctly identifies unique firm-year pairs. If there are duplicate rows or missing index values,plmwill behave unpredictably.
3. Syntax Typos or Overlapping Controls
- If you accidentally added redundant controls (e.g., using
effect = "twoways"ANDfactor(year)), you’re double-counting time effects, which leads to singular matrix errors and unstable coefficient estimates. - Typos in variable names (e.g.,
fleet_endvsfleet_end_) can cause variables to be excluded unexpectedly, making models look identical on paper but different in practice.
- Share the Full Code for Model 2 & 3: Post the complete code for both models—this will let us spot exactly where the specifications diverge.
- Check Variable Time Variation: Run
table(dt.airline$code, dt.airline$country)to see if any firms switch countries. If no firms do,countryis time-invariant and shouldn’t be added to a firm fixed effect model. - Inspect the Error Message: Copy-paste the exact error text—messages like "singular matrix" point to multicollinearity, while "variable not found" means a typo.
- Verify Panel Balance: Convert your data to a
pdata.frameand check balance:
If it’s unbalanced, see howpdt <- pdata.frame(dt.airline, index = c('code','year')) is.pbalanced(pdt)plmis handling missing observations vs your manual dummy approach.
Suppose your Model 2 was:
# Pooled OLS with time + country dummies Model2 <- plm(op_margin ~ pur_dum + log(firm_age) + log(fleet_end) + factor(year) + factor(country), data = dt.airline, index = c('code','year'), model = "pooling")
And you thought Model 3 should match, but wrote:
# Two-way fixed effects (firm + time) without country dummies Model3 <- plm(op_margin ~ pur_dum + log(firm_age) + log(fleet_end), data = dt.airline, index = c('code','year'), model = "within", effect = "twoways")
These aren’t equivalent! To make them match (if country is time-varying), you’d need to add factor(country) to Model 3:
# Two-way fixed effects + country dummies (only if country varies over time!) Model3 <- plm(op_margin ~ pur_dum + log(firm_age) + log(fleet_end) + factor(country), data = dt.airline, index = c('code','year'), model = "within", effect = "twoways")
But if country is time-invariant, drop factor(country) from both models, or use a random effects model if you need to estimate country effects.
内容的提问来源于stack exchange,提问作者Flash321

