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
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