Using stargazer with a list of lm objects created by lapply-ing over a split data.frame
Asked Answered
P

1

8

I'm trying to create a stargazer table for a set of regressions, where I ran each regression on a subset of my data. The natural way to do this, I would think, is to use split to create a list of data.frames from my data, create a list of lm objects by using lapply on the list of data.frames, and then feed that list to stargazer. For example,

library(MASS)
library(stargazer)

data(Boston)

# This doesn't work
by.river <- split(Boston, Boston$chas)
fit <- lapply(by.river, lm, formula = crim ~ indus)
stargazer(fit, type = "text")

# % Error: Unrecognized object type.
# % Error: Unrecognized object type.

If I divide them up manually, this works fine:

# This works
fit2 <- vector(mode = "list", length = 2)
fit2[[1]] <- lm(crim ~ indus, data = Boston, subset = (chas == 0))
fit2[[2]] <- lm(crim ~ indus, data = Boston, subset = (chas == 1))
stargazer(fit2, type = "text")

But with my real data, the thing I'm splitting by has several values, and I would rather not split them all up by hand. Any ideas why I'm getting the "% Error: Unrecognized object type." error?

Psychro answered 13/1, 2015 at 20:55 Comment(4)
I really do not know why you (and now me as well) should be getting that error. The help page suggests that a list of model objects should be acceptable input. The only difference I can see between fit and fit2 is that fit is numbered.Malvia
It might have something to do with how the lm object stores function calls. If you do lapply(fit, summary), you get Call: FUN(formula = ..1, data = X[[1L]]), versus lapply(fit2, summary), which gives Call: lm(formula = crim ~ indus, data = Boston, subset = (chas == 0)). But that's the closest I can figure out.Psychro
Very interesting. So the fit2 item are stored as calls but not evaluated until they are needed. Sounds like another effect of R's lazy evaluation mechanism. stargazer is then seeing an unevaluated expression and doesn't push it through the evaluation mechanism. It might be worth a note to the package maintainer.Malvia
Did anyone already this to the package maintainer? I believe that getting lapply(formulas, lm, data=my.data) working would be worthwhile.Scholl
D
8

There is an easy workaround, hinted at by BondedDust and suggested by careful perusal of the help for lapply.

fit <- lapply(by.river, function(dd)lm(crim ~ indus,data=dd))
stargazer(fit, type = "text")
fit[[1]]$call
#lm(formula = crim ~ indus, data = dd)
Dastard answered 20/9, 2015 at 20:12 Comment(2)
Too bad it doesn't work without the anonymous function, but this seems like a reasonable workaround.Psychro
It has to be something to do with how stargazer identifies the type of object. functions in package AICcmodavg are fine with lists of models created this way.Dastard

© 2022 - 2024 — McMap. All rights reserved.