Search code examples
rxtable

Including model specifications in xtable(anova(...))


I have a bunch of loglinear models, which, for our purposes will just be glm() objects called mx, my, mz. I want to get a nicely-formatted xtable of the analysis of deviance, so naturally I would want to perform xtable(anova(mx, my, mz, test = "Chisq")).

The vanilla output of xtable, however, doesn't include the model specifications. I'd like to include those for all the ANOVA tests I'm running, so if there is not a param I'm missing that does this I'll probably just have to hack up my own solution. But looking over the help page, there doesn't seem to be an easy way to include the model specifications.

Any thoughts? Alternatives?

If it helps this was done in 2.9.1 with xtable 1.5-5.


Solution

  • if a is the anova table object, then attr(a,"heading") does contain the information you are looking for, but I couldn't figure out a nice way of extracting it. So I looked up the code of anova.glm, which directed me to the code of anova.lmlist to figure out how they put that information into the heading. This inspired to following solution:

    # fake data
    x <- 1:10
    y <- x+ rnorm(10)
    
    # two models
    m1 <- glm(y~x)
    m2 <- glm(y~x+I(x^2))
    a <- anova(m1, m2)  # anova object to be printed
    
    # get model formulas
    flas <- sapply(list(m1,m2), function(x)paste(deparse(x$formula)))
    rownames(a) <- flas  # add formulas as rownames
    
    # convert to latex
    xtable(a)
    

    Edit to cater for long formulas:
    If you have long formulas, two changes are needed: first we have to make sure that deparse does not break it into lines, and then we need to make latex to wrap the formula in the table. The first can be achieved by using the cutoff.width argument of deparse, and the second by using a p{width} column type in latex. For example:

    # add long formula
    m2$formula <- freq ~ sex + attend + birth + politics + sex:attend + sex:birth + 
                  sex:politics + attend:birth + attend:politics + birth:politics + 
                  sex:attend:birth + sex:attend:politics + sex:birth:politics +
                  attend:birth:politics
    a <- anova(m1, m2) 
    
    # use a large width
    flas <- sapply(list(m1,m2), 
                   function(x)paste(deparse(x$formula, cutoff.width=500)))
    rownames(a) <- flas  # add formulas as rownames
    
    # convert to latex with first column wrapped in a 5cm wide parbox
    xtable(a, align="p{5cm}rrrr")
    

    The result is not overly pretty, but your formula is not pretty either. In this particular case I would use (sex + attend + birth + politics)^3 - gets the point across and is much shorter.