What I am trying to do should be fairly easy: I estimate a tobit model using the R package Zelig. From this I want to create a tex output using texreg. But what I get back is the error message:
Error in (function (classes, fdef, mtable) : unable to find an inherited method for function ‘extract’ for signature ‘"Zelig-tobit"’
This is rather strange as texreg does have an extraction method for tobit models. I also tried specifying a function myself but could not get it to work. Here is an example code:
library(Zelig)
library(texreg)
a <- c(2, 2, 2, 4, 3, 5, 9, 9, 9)
b <- c(18, 20, 19, 17, 22, 48, 12, 22, 37)
c <- c(0.1, 0.02, 0.5, 1.2, 0.9, 0.1, 1.1, 0.7, 0.6)
dat <- data.frame(a, b, c)
model <- zelig(a ~ b + c, below = 2, above = 9, model = "tobit", data = dat)
texreg(model)
I am using R Studio on a Windows computer, the texreg version is 1.36.4 and the Zelig version 5.0-11.
This question seemed closely related to my problem: texreg-ing Tobit output from zelig package (R)
However, according to this it should have been fixed a few versions ago, which is not the case for me.
Thanks in advance for your help!
(Btw, I also tried using stargazer instead of texreg which yielded me just another error message.)
I tried to write my own extract function but due to my amateurishness in function writing can't get it to work. Here is what I did:
extract.tob <- function(model, include.iterations = TRUE, include.loglik = TRUE,
include.wald = TRUE, ...) {
s <- model
names <- rownames(s$coef)
co <- s$coef[, 1]
se <- s$coef[, 2]
pval <- s$coef[, 4]
gof <- numeric()
gof.names <- character()
gof.decimal <- logical()
if (include.iterations == TRUE) {
it <- s$iterations
gof <- c(gof, it)
gof.names <- c(gof.names, "Number of\\iterations")
gof.decimal <- c(gof.decimal, TRUE)
}
if (include.loglik == TRUE) {
ll <- s$logLik
gof <- c(gof, ll)
gof.names <- c(gof.names, "Log-\\likelihood")
gof.decimal <- c(gof.decimal, TRUE)
}
if (include.wald == TRUE) {
wd <- s$wald
gof <- c(gof, wd)
gof.names <- c(gof.names, "Wald-\\statistic")
gof.decimal <- c(gof.decimal, 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("Zelig-tobit", "Zelig"),
definition = extract.tob)
As I see it, the zelig model is already "summarized", that is why I set s <- model instead of summary(model) as in the example. My main problem seems to be that I can't get the needed statistics (log-likelihood, wald ...) out of the model as I do not know how to adress them. The output of str() and so on does not help me with this. Apart from simply not knowing the "names" of the statistics, there also seems to be a problem with how to adress them.
When I try something like "model$coef" I get:
Error in envRefInferField(x, what, getClass(class(x)), selfEnv) :
‘coef’ is not a valid field or method name for reference class “Zelig-tobit”
With "model@coef" I get:
Error: no slot of name "coef" for this object of class "Zelig-tobit"
And model[,1] yields me:
Error in modelt6[, 1] : object of type 'S4' is not subsettable
Does anyone have any idea how to make the extract function work? Or another, easier way to get the model output into Latex?
It looks like Zelig-tobit
objects as defined in the Zelig
package are merely containers that include tobit
objects as defined in the AER
package, among other things. Therefore you should be able to run texreg
on the tobit
object that is contained in model
:
screenreg(model$zelig.out$z.out[[1]])
yields:
==========================
Model 1
--------------------------
(Intercept) -18.42
(16.34)
b 0.49
(0.36)
c 17.51
(11.49)
Log(scale) 1.76 ***
(0.49)
--------------------------
AIC 33.55
BIC 34.34
Log Likelihood -12.78
Deviance 9.46
Total 9
Left-censored 3
Uncensored 3
Right-censored 3
Wald Test 2.35
==========================
*** p < 0.001, ** p < 0.01, * p < 0.05
It is possible to write an extract
method to do that automatically. Here is an example:
# extension for Zelig-tobit objects (Zelig package)
extract.Zeligtobit <- function(model, include.aic = TRUE, include.bic = TRUE,
include.loglik = TRUE, include.deviance = TRUE, include.nobs = FALSE,
include.censnobs = TRUE, include.wald = TRUE, ...) {
e <- extract(model$zelig.out$z.out[[1]], include.aic = include.aic,
include.bic = include.bic, include.loglik = include.loglik,
include.deviance = include.deviance, include.nobs = include.nobs,
include.censnobs = include.censnobs, include.wald = include.wald, ...)
return(e)
}
setMethod("extract", signature = className("Zelig-tobit", "Zelig"),
definition = extract.Zeligtobit)
Now you can just write:
screenreg(model)
which yields the same output as above.
I never quite understood why people use Zelig
instead of the original packages like AER
. Zelig
merely provides wrappers for other existing estimation functions and thereby complicates the data structures in an unnecessary way. E.g., why do you not just use the AER
package?