Search code examples
rstargazertexregr-zelig

R: creating tex output from zelig tobit model with texreg


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?


Solution

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