tags:

views:

282

answers:

2

Hello R comrades:

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.

+4  A: 

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.

Aniko
This is a great start, but it sort of breaks down further up the interaction hierarchy. For instance, if I have `[[3]][1] "freq ~ sex + attend + birth + politics + sex:attend + sex:birth + " [2] " sex:politics + attend:birth + attend:politics + birth:politics + "[3] " sex:attend:birth + sex:attend:politics + sex:birth:politics + " [4] " attend:birth:politics" `It doesn't work! So close though - seems the solution would include putting up the long-form models agove the table, and numbering them, and then just referring to the number in the actual table.
HamiltonUlmer
I have added an example with your long formula.
Aniko
+1  A: 

I reckon that you want to get LaTeX table, but you can easily get HTML table with model formula.

# if we presuppose that <b>a</b> is object from @Aniko's reply
> class(a)
[1] "anova"      "data.frame"
# after doing a bit of that sapply magic you get
> a
Analysis of Deviance Table

Model 1: y ~ x
Model 2: y ~ x + I(x^2)
               Resid. Df Resid. Dev Df Deviance
y ~ x                  8     15.503            
y ~ x + I(x^2)         7     12.060  1   3.4428

You can do something like this:

# load xtable library
library(xtable)
# sink output to html file
sink("~/anova_specs.html")  # suppose you're running R on Linux "~/"
print(xtable(a), type = "html")
sink()

It's not as pretty as LaTeX table, but it has model formula...

aL3xa