Search code examples
rregressionstargazer

FELM + Stargazer - Align instrumental variables estimates with OLS


I have an felm object in R that I'm trying to make a table comparing the coefficient estimates from OLS estimation and IV estimation. The code below produces a table with two coefficient estimates, x and `x(fit)` in separate rows.

library(lfe)
library(stargazer)
n<-1000

u1<-rnorm(n)
u2<-rnorm(n)
z=3+0.5*rnorm(n)

x=0.5*z+u1
y=2*x+u2

df<-data.frame(y=y,x=x,z=z)

model1<-felm(y~x,data=df)
model2<-felm(y~1|0|(x~z),data=df)

stargazer(model1, model2, df)

===========================================================
                                   Dependent variable:     
                               ----------------------------
                                            y              
                                    (1)            (2)     
-----------------------------------------------------------
x                                 2.003***                 
                                  (0.031)                  

`x(fit)`                                        1.795***   
                                                 (0.149)   

Constant                           -0.041         0.274    
                                  (0.057)        (0.227)   

-----------------------------------------------------------
Observations                       1,000          1,000    
R2                                 0.804          0.796    
Adjusted R2                        0.804          0.795    
Residual Std. Error (df = 998)     1.005          1.027    
===========================================================
Note:                           *p<0.1; **p<0.05; ***p<0.01

What I'd like to have is a table like the following:

===========================================================
                                   Dependent variable:     
                               ----------------------------
                                            y              
                                    (1)            (2)     
-----------------------------------------------------------
x                                 2.003***        1.795***         
                                  (0.031)        (0.149)                                            

Constant                           -0.041         0.274    
                                  (0.057)        (0.227)   

-----------------------------------------------------------
Observations                       1,000          1,000    
R2                                 0.804          0.796    
Adjusted R2                        0.804          0.795    
Residual Std. Error (df = 998)     1.005          1.027    
===========================================================
Note:                           *p<0.1; **p<0.05; ***p<0.01

I tried doing

rownames(model2$coefficients)[rownames(model2$coefficients=="`x(fit)`"]<-"x"

but ran into an error in the Wald test. This is also annoying to do if I have multiple variables for which I'm instrumenting.

Is there a simpler way to align the covariates from different rows in Stargazer or R more broadly?


Solution

  • If you use texreg instead of stargazer this is fairly straightforward:

    library(lfe)
    library(texreg)
    
    n<-1000
    
    u1<-rnorm(n)
    u2<-rnorm(n)
    z=3+0.5*rnorm(n)
    
    x=0.5*z+u1
    y=2*x+u2
    
    df<-data.frame(y=y,x=x,z=z)
    
    model1<-felm(y~x,data=df)
    model2<-felm(y~1|0|(x~z),data=df)
    
    screenreg(list(model1, model2), 
              custom.coef.names = c("(Intercept)", "x", "x"))
    #> 
    #> ===============================================
    #>                        Model 1      Model 2    
    #> -----------------------------------------------
    #> (Intercept)               0.05         0.11    
    #>                          (0.05)       (0.13)   
    #> x                         1.98 ***     1.93 ***
    #>                          (0.03)       (0.09)   
    #> -----------------------------------------------
    #> Num. obs.              1000         1000       
    #> R^2 (full model)          0.82         0.81    
    #> R^2 (proj model)          0.82         0.81    
    #> Adj. R^2 (full model)     0.81         0.81    
    #> Adj. R^2 (proj model)     0.81         0.81    
    #> ===============================================
    #> *** p < 0.001, ** p < 0.01, * p < 0.05
    

    As you can see this works by specifying a vector of coefficient labels, and if texreg finds these values duplicated it will place those estimates on the same row (incidentally to generate latex use texreg(list(model1, model2)) instead of screenreg).

    Also worth noting that if you insert an NA into custom.coef.names it will default back to the current name, so if you have 100 other covariates in the model, you could do custom.coef.names = c(NA, "x", "x", rep(NA, 100)) instead of writing them all out.