grantmcdermott / etwfe

Extended two-way fixed effects
https://grantmcdermott.com/etwfe/
Other
51 stars 11 forks source link

Interacted Treatment Effect #13

Closed frederickluser closed 1 year ago

frederickluser commented 1 year ago

Dear Grant,

Thanks for your amazing work. Wooldridge's estimator allows interacting a binary treatment dummy with a time-constant covariate (say, gender - male / female). Then, you get the effect separately for all groups. I tried to implement the estimator including this feature on my own, but it's buggy and occasionally the standard errors explode (Too small groups etc.)

Are you planning to include this interaction-option in your package, or did you even already implement it?

Thanks and best, Frederic

grantmcdermott commented 1 year ago

Hi Frederick,

Great to hear that you're finding the package useful.

I'm in the middle a CRAN submission and am facing some formidable time constraints at present. But I'll try to take a look at this soon. Do you have an example dataset / regression, so I have something specific to benchmark against?

frederickluser commented 1 year ago

Dear Grant, thank you for your swift reply. I would love to see interacted covariates in your packages, as I think that this is a strong feature that the other new DID estimators cannot provide.

I attached a small fake data set here (and also my etwfe function for completeness): dat.zip

The regression is basically nothing else than this (at least I think so):

    mod <- feols(y ~ w:g:t:x_demean + w:g:t + t:x  | i + t, data) 

And here follows some sample code. So maybe you find this interesting and will implement it at some point. All the best, Frederic

# Setup
source("mundlak_fct.R")
dat <- readRDS("dat.rds") %>% as_tibble() %>% 
     mutate(treat = ifelse(year >= cohort, 1, 0) )

# WITHOUT COVARIATES

# a standard pre/post DiD
feols(y ~ treat | year + firm, dat)

OLS estimation, Dep. Var.: y
Observations: 3,600 
Fixed-effects: year: 36,  firm: 100
Standard-errors: Clustered (year) 
      Estimate Std. Error t value   Pr(>|t|)    
treat 0.495561     0.0417  11.884 7.7052e-14 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
RMSE: 0.512264     Adj. R2: 0.673737
                 Within R2: 0.060662

#------------------------------------------------------------
# my implementation of Wooldridge
etwfe(y = "y", t = "year", g = "cohort", i = "firm", x = NULL, data = dat)

# A tibble: 1 × 7
    att    se     t     p ci_low ci_high     n
  <dbl> <dbl> <dbl> <dbl>  <dbl>   <dbl> <int>
1 0.479 0.035  13.7     0  0.410   0.548  3600

#############################################
# WITH AN INTERACTED COVARIATE

# a standard pre/post DiD
feols(y ~ treat*x | year + firm, dat)

OLS estimation, Dep. Var.: y
Observations: 3,600 
Fixed-effects: year: 36,  firm: 100
Standard-errors: Clustered (year) 
         Estimate Std. Error  t value   Pr(>|t|)    
treat    0.439747   0.048866  8.99908 1.2420e-10 ***
x       -0.078118   0.047506 -1.64438 1.0905e-01    
treat:x  0.109584   0.064349  1.70296 9.7442e-02 .  
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
RMSE: 0.51198     Adj. R2: 0.673912
                Within R2: 0.061706

#------------------------------------------------------------
# my implementation of Wooldridge
etwfe(y = "y", t = "year", g = "cohort", i = "firm", x = "x", data = dat)

# A tibble: 2 × 8
  variable   att    se     t     p ci_low ci_high     n
  <chr>    <dbl> <dbl> <dbl> <dbl>  <dbl>   <dbl> <int>
1 w        0.467 0.07  6.67   0     0.330   0.604  3600
2 w_x      0.033 0.114 0.289  0.77 -0.190   0.256  3600