Search code examples
rbroomlfe

Using broom::tidy on felm result with clustered standard errors


I'm trying to extract point estimates and confidence intervals from a panel data model. The following reproduces the error using the canned example from the lfe documentation. The only small change I've made is to cluster standard errors at the firm-level to replicate my issue in est2.

## create covariates
x <- rnorm(1000)
x2 <- rnorm(length(x))

## individual and firm
id <- factor(sample(20,length(x),replace=TRUE))
firm <- factor(sample(13,length(x),replace=TRUE))

## effects for them
id.eff <- rnorm(nlevels(id))
firm.eff <- rnorm(nlevels(firm))

## left hand side
u <- rnorm(length(x))
y <- x + 0.5*x2 + id.eff[id] + firm.eff[firm] + u

## estimate and print result
est1 <- felm(y ~ x+x2| id + firm)
summary(est1)

## estimate and print result with clustered std errors
est2 <- felm(y ~ x+x2| id + firm | 0 | firm)
summary(est2)

I can tidy in the non-clustered SE version or without including the fixed effects:

tidy(est1)
tidy(est2)
tidy(est1, fe = TRUE)

But I can't if I ask for the fixed effects:

tidy(est2, fe = TRUE)

The error is this: Error in overscope_eval_next(overscope, expr) : object 'se' not found

I'm not sure if this is a broom side problem or an lfe side problem. It is possible I'm doing something wrong, but there should be point estimates and standard errors for the fixed effects whether or not I cluster the SEs. (And the fact that there are fewer clusters than FEs is probably an econometric issue, but it doesn't seem to be driving this particular problem.) Any suggestions?


Solution

  • The problem here is that lfe::getfe() is supposed to return the columns c('effect','se','obs','comp','fe','idx') according to its help page. However, if you run

    lfe::getfe(est1, se = TRUE) and

    lfe::getfe(est2, se = TRUE)

    in the second instance, the standard errors are in a column named clusterse instead of se.

    The error message is a result of the function broom:::tidy.felm using lfe::getfe() and then dplyr::select(se).

    I guess technically it's an lfe problem but I'm not sure which package will be easier to amend

    Update: I emailed Simen Gaure (the package author) and he'll be releasing to CRAN some time this spring