4

I've been running a bunch of different regression models and would now like to get their estimates into a LaTeX table. To make the different specifications comparable I would like to use the kind of table that outreg from the rockchalk package or mtable from memisc produce, i.e. one in which the different models are shown in columns and parameter estimates from those models are shown in the appropriate rows. This is what I've got:

df <- data.frame(x=rnorm(20),
                 z=rnorm(20),
                 group=gl(5,4,20,labels=paste('group',rep(1:5))))
df$y = 5 + 2*df$x + 5*df$z + rep(c(3.2,5,6.2,8.2,5),each=4) + rnorm(20)

model1 <- lm(y ~ x + z + factor(group),data=df)
model2 <- lm(y ~ x + factor(group),data=df)
model3 <- lm(y ~ x + z,data=df)

library(memisc)

reg.table <- mtable("Model 1"=model1,"Model 2"=model2,"Model 3"=model3,
                summary.stats=c("sigma","R-squared","F","p","N"))

toLatex(reg.table)

This works well enough, but I've got a factor with roughly 200 levels and a correspondingly large number of coefficients. What I'd like to do is to either omit the coefficients associated with this factor from the table or (for bonus points!) to show that the factor was used in the model with a simple 'yes' or 'no'. So, my ideal output would be this:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%    %
%
% Calls:
% Model 1:  lm(formula = y ~ x + z + factor(group), data = df) 
% Model 2:  lm(formula = y ~ x + factor(group), data = df) 
% Model 3:  lm(formula = y ~ x + z, data = df) 
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%    %
\begin{tabular}{lcD{.}{.}{7}cD{.}{.}{7}cD{.}{.}{7}}
\toprule
&&\multicolumn{1}{c}{Model 1} && \multicolumn{1}{c}{Model 2} && \multicolumn{1}{c}{Model 3}\\
\midrule
(Intercept)                    &  &  8.315^{***} &&    4.235     && 10.338^{***}\\
                               &  &  (0.537)     &&   (3.276)    &&  (0.468)    \\
x                              &  &  1.976^{***} &&    2.398     &&  1.858^{***}\\
                               &  &  (0.238)     &&   (1.530)    &&  (0.443)    \\
z                              &  &  5.389^{***} &&              &&  5.359^{***}\\
                               &  &  (0.226)     &&              &&  (0.463)    \\
group                          &  &   yes        &&    yes       &&     no      \\
\midrule
sigma                          &  &     0.929    &&     5.981    &&     2.092   \\
R-squared                      &  &     0.984    &&     0.265    &&     0.891   \\
F                              &  &   129.485    &&     1.009    &&    69.306   \\
p                              &  &     0.000    &&     0.448    &&     0.000   \\
N                              &  &    20        &&    20        &&    20       \\
\bottomrule
\end{tabular}

Is this possible?

RoyalTS
  • 9,545
  • 12
  • 60
  • 101

1 Answers1

5

Just selecting the first three coefficients is pretty simple:

reg.table$coefficients <- reg.table$coefficients[,,1:3,,drop=FALSE]
toLatex(reg.table)

The "bonus" question (i.e. adding a hand-built 4th row describing "group") requires a bit more work:

## Select the first three coeffients + one to be modified
reg.table$coefficients <- reg.table$coefficients[,,1:4,,drop=FALSE]

## Make a copy of all the coefficients, and in the copy, modify the 4th
j <- reg.table$coefficients
j[,,4,] <- c("yes", "", "yes", "", "no", "")
dimnames(j)[[3]][4] <- "group"

## Put the modified coefficients back into `reg.table`
reg.table$coefficients <- j

et voila

toLatex(reg.table)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Calls:
% Model 1:  lm(formula = y ~ x + z + factor(group), data = df) 
% Model 2:  lm(formula = y ~ x + factor(group), data = df) 
% Model 3:  lm(formula = y ~ x + z, data = df) 
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{tabular}{lcD{.}{.}{7}cD{.}{.}{7}cD{.}{.}{7}}
\toprule
&&\multicolumn{1}{c}{Model 1} && \multicolumn{1}{c}{Model 2} && \multicolumn{1}{c}{Model 3}\\
\midrule
(Intercept) &  &   8.830^{***} &&   9.846^{**}  && 10.342^{***} \\
            &  &   (0.626)     &&    (3.272)    &&   (0.442)    \\
x           &  &   2.047^{***} &&     1.765     &&  1.937^{***} \\
            &  &   (0.244)     &&    (1.276)    &&   (0.319)    \\
z           &  &   5.138^{***} &&               &&  4.847^{***} \\
            &  &   (0.267)     &&               &&   (0.372)    \\
group       &  &  yes          &&   yes         &&   no         \\
            &  &               &&               &&              \\
\midrule
sigma       &  &     1.204     &&     6.310     &&      1.812   \\
R-squared   &  &     0.975     &&     0.270     &&      0.927   \\
F           &  &    85.576     &&     1.033     &&    107.717   \\
p           &  &     0.000     &&     0.436     &&      0.000   \\
N           &  &    20         &&    20         &&     20       \\
\bottomrule
\end{tabular}

Edit:

Here's a version I like even better. It addresses the OP's 1st comment below, and uses abind() (like rbind() for arrays) to add the group info to the array, which I find to be cleaner:

library(abind)

j <- reg.table$coefficients

groupFac <- array(c("yes", "", "yes", "", "no", ""), dim=c(2,1,3))
nonGroupFacs <- which(!grepl("group", dimnames(j)[[3]]))
j <- j[,,nonGroupFacs,,drop=FALSE]
j <- abind(j, groupFac, along=3)
dimnames(j)[[3]][length(nonGroupFacs)+1] <- "group"

reg.table$coefficients <- j

toLatex(reg.table)
Josh O'Brien
  • 159,210
  • 26
  • 366
  • 455
  • Fantastic, thank you very much! Is there any way I could select the rows by name rather than by row numbers, e.g. all rows whose names don't start with `factor` or some such? – RoyalTS Jun 14 '12 at 23:49
  • 1
    You're welcome! See my latest edit, which addresses your comment, and uses a nicer syntax for adding the `group` summary to the `coefficients` array. – Josh O'Brien Jun 15 '12 at 00:36
  • Thank you once again, that was very helpful. After playing around with all this some more, I found that the `apsrtable` package ([see vignette here](http://cran.r-project.org/web/packages/apsrtable/vignettes/guide.pdf)) actually does all this (and much more) without having to muck around with the internals. – RoyalTS Jun 15 '12 at 13:17
  • @RoyalTS Nice find. Looks like that might come in handy for me as well. – Josh O'Brien Jun 15 '12 at 18:32
  • Note for anyone still reading along: The `stargazer` package might also be worth considering to do this kind of thing. – RoyalTS Jan 05 '13 at 13:03