Search code examples
rregressionstargazerlfe

R stargazer package output: Missing F statistic for felm regression (lfe package)


I am trying to use the stargazer package to output my regression results. I performed my regressions using felm from the lfe package. The stargazer output tables shows everything properly except the F statistic values which remain blank. The issue does not arise with the lm results.

What is the reason and how can I get F statistic values for my felm regressions to appear in the stargazer output?

I know I can manually add a line to show the F-values but I would prefer a more automatic approach if it's possible.

Below is a sample code using data provided here

library(foreign)
temp_dat <- read.dta("http://www.kellogg.northwestern.edu/faculty/petersen/htm/papers/se/test_data.dta")

temp_lm <- lm(y ~ x, temp_dat)
temp_felm <- felm(y ~ x, temp_dat)

library(stargazer)
stargazer(temp_lm, temp_felm, type = "text")

Output:

====================================================================
                                        Dependent variable:         
                                ------------------------------------
                                                 y                  
                                            OLS               felm  
                                            (1)               (2)   
--------------------------------------------------------------------
x                                        1.035***           1.035***
                                          (0.029)           (0.029) 

Constant                                   0.030             0.030  
                                          (0.028)           (0.028) 

--------------------------------------------------------------------
Observations                               5,000             5,000  
R2                                         0.208             0.208  
Adjusted R2                                0.208             0.208  
Residual Std. Error (df = 4998)            2.005             2.005  
F Statistic                     1,310.740*** (df = 1; 4998)         
====================================================================
Note:                                    *p<0.1; **p<0.05; ***p<0.01


Solution

  • There doesn't seem to be a way to automate within stargazer, which is great package, but is not extensible. The option keep.stat = "f" does not produce an f-stat for the felm object. However, texreg has an option that includes the f-stat for felm objects.

    library(foreign);library(texreg);library(lfe)
    temp_dat <- read.dta("http://www.kellogg.northwestern.edu/faculty/petersen/htm/papers/se/test_data.dta")
    
    temp_lm <- lm(y ~ x, temp_dat)
    temp_felm <- felm(y ~ x, temp_dat)
    
    screenreg(list(temp_lm, temp_felm), include.fstatistic = T)
    

    Produces:

    ==================================================
                              Model 1      Model 2    
    --------------------------------------------------
    (Intercept)                  0.03         0.03    
                                (0.03)       (0.03)   
    x                            1.03 ***     1.03 ***
                                (0.03)       (0.03)   
    --------------------------------------------------
    R^2                          0.21                 
    Adj. R^2                     0.21                 
    Num. obs.                 5000         5000       
    F statistic               1310.74                 
    RMSE                         2.01                 
    R^2 (full model)                          0.21    
    R^2 (proj model)                          0.21    
    Adj. R^2 (full model)                     0.21    
    Adj. R^2 (proj model)                     0.21    
    F statistic (full model)               1310.74    
    F (full model): p-value                   0.00    
    F statistic (proj model)               1310.74    
    F (proj model): p-value                   0.00    
    ==================================================
    *** p < 0.001, ** p < 0.01, * p < 0.05
    

    The createTexreg function allows you to choose the specific stats you wish to extract and display. You first need to write a little function to extract objects from the summary.felm object and then turn that into a texreg object.

    extract.felm <- function(model, include.f.full = TRUE, 
                             include.f.proj = TRUE,
                             include.rsquared = TRUE,
                             include.adjrs = TRUE, 
                             include.nobs = TRUE, ...) {
    
       s <- summary(model, ...)
       names <- rownames(s$coefficients)
       co <- s$coefficients[, 1]
       se <- s$coefficients[, 2]
       pval <- s$coefficients[, 4]
    
        gof <- numeric()
        gof.names <- character()
        gof.decimal <- logical()
        if (include.rsquared == TRUE) {
          rs <- s$r.squared
          gof <- c(gof, rs)
          gof.names <- c(gof.names, "R$^2$")
          gof.decimal <- c(gof.decimal, TRUE)
          }
       if (include.adjrs == TRUE) {
         adj <- s$adj.r.squared
         gof <- c(gof, adj)
         gof.names <- c(gof.names, "Adj.\\ R$^2$")
         gof.decimal <- c(gof.decimal, TRUE)
         }
       if (include.nobs == TRUE) {
         n <- s$N
         gof <- c(gof, n)
         gof.names <- c(gof.names, "Num.\\ obs.")
         gof.decimal <- c(gof.decimal, FALSE)
       }
        if (include.f.full == TRUE) {
          ffs <- s$fstat
          ffpval <- round(s$F.fstat[4],4)
          gof <- c(gof, ffs, ffpval)
          gof.names <- c(gof.names, "F statistic (Full model)", "F (full model): p-value")
          gof.decimal <- c(gof.decimal, TRUE, TRUE)
        }
        if (include.f.proj == TRUE) {
          fps <- s$P.fstat[5]
          fppval <- s$P.fstat[4]
          gof <- c(gof, fps, fppval)
          gof.names <- c(gof.names, "F statistic (proj. model)", "F (proj. model): p-value") #Modify the names as you see fit
          gof.decimal <- c(gof.decimal, TRUE, TRUE)
        }
         tr <- createTexreg(
           coef.names = names,
           coef = co,
           se = se,
           pvalues = pval,
           gof.names = gof.names,
           gof = gof,
           gof.decimal = gof.decimal
           )
       return(tr)
       }
    setMethod("extract", signature = className("felm", "stats"),
                 definition = extract.felm)
    

    Now, run the function, setting the argument include.f.prof = F and send it to screenreg:

    > m <- extract.felm(temp_felm, include.f.proj = F)
    > screenreg(list(temp_lm, m))
    
    ==================================================
                              Model 1      Model 2    
    --------------------------------------------------
    (Intercept)                  0.03         0.03    
                                (0.03)       (0.03)   
    x                            1.03 ***     1.03 ***
                                (0.03)       (0.03)   
    --------------------------------------------------
    R^2                          0.21         0.21    
    Adj. R^2                     0.21         0.21    
    Num. obs.                 5000         5000       
    RMSE                         2.01                 
    F statistic (Full model)               1310.74    
    F (full model): p-value                   0.00    
    ==================================================
    *** p < 0.001, ** p < 0.01, * p < 0.05