5

I'm using xtable to manage R output in Sweave. See code below:

CC <- data.frame(
    y = c(449, 413, 326, 409, 358, 291, 341, 278, 312)/12,
    P = ordered(gl(3, 3)), N = ordered(gl(3, 1, 9))
)
CC.aov <- aov(y ~ N * P, data = CC , weights = rep(12, 9))
Summary <- summary(CC.aov, split = list(N = list(L = 1, Q = 2),
                                        P = list(L = 1, Q = 2)))
Summary

            Df Sum Sq Mean Sq
N            2 1016.7   508.3
  N: L       1 1012.5  1012.5
  N: Q       1    4.2     4.2
P            2  917.4   458.7
  P: L       1  917.3   917.3
  P: Q       1    0.0     0.0
N:P          4  399.3    99.8
  N:P: L.L   1  184.1   184.1
  N:P: Q.L   1  152.1   152.1
  N:P: L.Q   1   49.0    49.0
  N:P: Q.Q   1   14.1    14.1

I like to indent the first column as shown in the output above. But when I use xtable(Summary) the first column is aligned left. I know how to align left, right or center but could not figure out how to get the output as indented in the first. Any help in this regard will be highly appreciated. Thanks

MYaseen208
  • 22,666
  • 37
  • 165
  • 309
  • This will probably require a more in depth LaTeX solution, maybe like what's described [here](http://tex.stackexchange.com/questions/20523/change-alignment-for-individual-table-rows), which _might_ be doable by hacking the `sanitize.text.function` argument. The other option is the more flexible LaTeX commands in **Hmisc** package. – joran Feb 08 '12 at 06:21

2 Answers2

10

This example shows how to customize the table combining the use of the sanitize argument in xtable and the function \hskip in latex.

The code would be:

named = rownames(Summary[[1]])
tags= gsub("  "," ",named)
rownames(Summary[[1]])= c(ifelse(nchar(tags)<8,tags,paste("\\hskip .5cm",tags,sep=' ')))
print(xtable(Summary[[1]]), type="latex", sanitize.text.function = function(x){x})

EDIT: Following Dwin's suggestion of using

grepl("^ ", rownames(Summary[[1]])

That provides a more general solution. The code would change to:

named = rownames(Summary[[1]])
tags= grepl("^ ", rownames(Summary[[1]]))
rownames(Summary[[1]])= c(ifelse(tags==F,named,paste("\\hskip .5cm",named,sep=' ')))
print(xtable(Summary[[1]]), type="latex", sanitize.text.function = function(x){x})

enter image description here

aatrujillob
  • 4,738
  • 3
  • 19
  • 32
  • (+1): Excellent answer. This is what I was looking for. Please append the snap of output for others too. Thanks again. – MYaseen208 Feb 08 '12 at 07:40
  • 1
    @DWin I didn't get the error. However your grepl("^ ", rownames(Summary[[1]]) is a huge improvement to my code. I will update my answer using it. Thanks!!! – aatrujillob Feb 08 '12 at 16:40
  • I deleted my comment about the error. Too much editing on my part. Glad you found value in the grepl() strategy. – IRTFM Feb 08 '12 at 16:55
  • Now it is more general. Awesome solution. Thanks – MYaseen208 Feb 08 '12 at 17:28
  • I can't reproduce these results. Sanitize text function only seems to work when values are encapsulated in `$`. For all other text, the usual formatting is applied. – AdamO Sep 19 '13 at 00:49
2

Edit the output of xtable to add another column and put empty column dividers in from of the onew you want to indent: (and assuming appropriate document header and footer.)

\begin{tabular}{llrrr}
  \hline
& fac & Df & Sum Sq & Mean Sq \\ 
  \hline
N   &        & 2 & 1016.67 & 508.33 \\ 
 &  N: L      & 1 & 1012.50 & 1012.50 \\ 
 & N: Q      & 1 & 4.17 & 4.17 \\ 
P  &        & 2 & 917.39 & 458.69 \\ 
 &  P: L      & 1 & 917.35 & 917.35 \\ 
 &  P: Q      & 1 & 0.04 & 0.04 \\ 
N:P   &      & 4 & 399.28 & 99.82 \\ 
 & N:P: L.L  & 1 & 184.08 & 184.08 \\ 
 &N:P: Q.L  & 1 & 152.11 & 152.11 \\ 
 &N:P: L.Q  & 1 & 49.00 & 49.00 \\ 
 &N:P: Q.Q  & 1 & 14.08 & 14.08 \\ 
\hline
\end{tabular}

enter image description here

IRTFM
  • 258,963
  • 21
  • 364
  • 487