1 %\VignetteIndexEntry{xtable Gallery}
\r
2 %\VignetteDepends{xtable}
\r
3 %\VignetteKeywords{LaTeX, HTML, table}
\r
4 %\VignettePackage{xtable}
\r
6 % \VignetteEngine{knitr::knitr}
\r
8 %**************************************************************************
\r
17 \documentclass[article, nojss]{jss}
\r
19 \usepackage{amsmath}
\r
20 \usepackage{graphicx}
\r
22 \usepackage{afterpage}
\r
23 \usepackage{hyperref}
\r
26 The \pkg{xtable} Gallery
\r
28 \author{Jonathan Swinton and others\\
\r
29 <jonathan@swintons.net>
\r
32 \Plainauthor{Jonathan Swinton, and others} %% comma-separated
\r
34 \Plaintitle{The xtable Gallery} %% without formatting
\r
36 \Shorttitle{\pkg{xtable} Gallery} %% a short title (if necessary)
\r
41 fig.path='figdir/fig', debug=TRUE, echo=TRUE
\r
43 options(replace.assign = TRUE, width = 60,
\r
44 tidy.opts = list(width.cutoff = 60))
\r
47 \usepackage{rotating}
\r
48 \usepackage{longtable}
\r
49 \usepackage{booktabs}
\r
50 \usepackage{tabularx}
\r
51 %\usepackage{hyperref}
\r
55 This document gives a gallery of tables which can be made by using
\r
56 the \texttt{xtable} package to create \LaTeX\ output. It doubles as
\r
57 a regression check for the package.
\r
61 \Keywords{Reproducible research, \LaTeX}
\r
65 E-mail: \email{jonathan@swintons.net}
\r
73 \subsection{Data frame}
\r
74 Load example dataset
\r
79 ## Demonstrate data.frame
\r
80 tli.table <- xtable(tli[1:10, ])
\r
81 digits(tli.table)[c(2,6)] <- 0
\r
84 print(tli.table, floating = FALSE)
\r
91 design.matrix <- model.matrix(~ sex*grade, data = tli[1:10, ])
\r
92 design.table <- xtable(design.matrix)
\r
95 print(design.table, floating = FALSE)
\r
100 fm1 <- aov(tlimth ~ sex + ethnicty + grade + disadvg, data = tli)
\r
101 fm1.table <- xtable(fm1)
\r
103 <<results='asis'>>=
\r
104 print(fm1.table, floating = FALSE)
\r
108 fm2 <- lm(tlimth ~ sex*ethnicty, data = tli)
\r
109 fm2.table <- xtable(fm2)
\r
111 <<results='asis'>>=
\r
112 print(fm2.table, floating = FALSE)
\r
115 \vspace{12pt}\textbf{\itshape An anova object}
\r
117 <<results='asis'>>=
\r
118 print(xtable(anova(fm2)), floating = FALSE)
\r
120 \vspace{12pt}\textbf{\itshape Another anova object}
\r
122 fm2b <- lm(tlimth ~ ethnicty, data = tli)
\r
124 <<results='asis'>>=
\r
125 print(xtable(anova(fm2b, fm2)), floating = FALSE)
\r
134 fm3 <- glm(disadvg ~ ethnicty*grade, data = tli, family = binomial())
\r
135 fm3.table <- xtable(fm3)
\r
137 <<results='asis'>>=
\r
138 print(fm3.table, floating = FALSE)
\r
141 \vspace{12pt}\textbf{\itshape An anova object}
\r
142 <<results='asis'>>=
\r
143 print(xtable(anova(fm3)), floating = FALSE)
\r
147 \subsection{More aov}
\r
151 ## Taken from help(aov) in R 1.1.1
\r
152 ## From Venables and Ripley (1997) p.210.
\r
153 N <- c(0,1,0,1,1,1,0,0,0,1,1,0,1,1,0,0,1,0,1,0,1,1,0,0)
\r
154 P <- c(1,1,0,0,0,1,0,1,1,1,0,0,0,1,0,1,1,0,0,1,0,1,1,0)
\r
155 K <- c(1,0,0,1,0,1,1,0,0,1,0,1,0,1,1,0,0,0,1,1,1,0,1,0)
\r
156 yield <- c(49.5,62.8,46.8,57.0,59.8,58.5,55.5,56.0,62.8,55.8,69.5,55.0,
\r
157 62.0,48.8,45.5,44.2,52.0,51.5,49.8,48.8,57.2,59.0,53.2,56.0)
\r
158 npk <- data.frame(block = gl(6,4), N = factor(N), P = factor(P),
\r
159 K = factor(K), yield = yield)
\r
160 npk.aov <- aov(yield ~ block + N*P*K, npk)
\r
161 op <- options(contrasts = c("contr.helmert", "contr.treatment"))
\r
162 npk.aovE <- aov(yield ~ N*P*K + Error(block), npk)
\r
165 <<results='asis'>>=
\r
166 print(xtable(npk.aov), floating = FALSE)
\r
169 \vspace{12pt}\textbf{\itshape An anova object}
\r
170 <<results='asis'>>=
\r
171 print(xtable(anova(npk.aov)), floating = FALSE)
\r
174 \vspace{12pt}\textbf{\itshape Another anova object}
\r
175 <<results='asis'>>=
\r
176 print(xtable(summary(npk.aov)), floating = FALSE)
\r
179 <<results='asis'>>=
\r
180 print(xtable(npk.aovE), floating = FALSE)
\r
184 <<results='asis'>>=
\r
185 print(xtable(summary(npk.aovE)), floating = FALSE)
\r
188 \subsection{More lm}
\r
192 ## Taken from help(lm) in R 1.1.1
\r
193 ## Annette Dobson (1990) "An Introduction to Generalized Linear Models".
\r
194 ## Page 9: Plant Weight Data.
\r
195 ctl <- c(4.17,5.58,5.18,6.11,4.50,4.61,5.17,4.53,5.33,5.14)
\r
196 trt <- c(4.81,4.17,4.41,3.59,5.87,3.83,6.03,4.89,4.32,4.69)
\r
197 group <- gl(2,10,20, labels = c("Ctl","Trt"))
\r
198 weight <- c(ctl, trt)
\r
199 lm.D9 <- lm(weight ~ group)
\r
201 <<results='asis'>>=
\r
202 print(xtable(lm.D9), floating = FALSE)
\r
206 <<results='asis'>>=
\r
207 print(xtable(anova(lm.D9)), floating = FALSE)
\r
210 \subsection{More glm}
\r
214 ## Taken from help(glm) in R 1.1.1
\r
215 ## Annette Dobson (1990) "An Introduction to Generalized Linear Models".
\r
216 ## Page 93: Randomized Controlled Trial :
\r
217 counts <- c(18,17,15,20,10,20,25,13,12)
\r
218 outcome <- gl(3,1,9)
\r
219 treatment <- gl(3,3)
\r
220 d.AD <- data.frame(treatment, outcome, counts)
\r
221 glm.D93 <- glm(counts ~ outcome + treatment, family = poisson())
\r
223 <<results='asis'>>=
\r
224 print(xtable(glm.D93, align = "r|llrc"), floating = FALSE)
\r
227 \subsection{prcomp}
\r
229 if(require(stats, quietly = TRUE)) {
\r
230 ## Demonstrate prcomp
\r
231 ## Taken from help(prcomp) in mva package of R 1.1.1
\r
233 pr1 <- prcomp(USArrests)
\r
236 <<results='asis'>>=
\r
237 if(require(stats, quietly = TRUE)) {
\r
238 print(xtable(pr1), floating = FALSE)
\r
243 <<results='asis'>>=
\r
244 print(xtable(summary(pr1)), floating = FALSE)
\r
249 <<echo = FALSE, results = 'Hide'>>=
\r
250 # ## Demonstrate princomp
\r
251 # ## Taken from help(princomp) in mva package of R 1.1.1
\r
252 # pr2 <- princomp(USArrests)
\r
253 # print(xtable(pr2))
\r
256 \subsection{Time series}
\r
259 temp.ts <- ts(cumsum(1 + round(rnorm(100), 0)),
\r
260 start = c(1954, 7), frequency = 12)
\r
261 temp.table <- xtable(temp.ts, digits = 0)
\r
262 caption(temp.table) <- "Time series example"
\r
264 <<results='asis'>>=
\r
265 print(temp.table, floating = FALSE)
\r
267 <<savetofile,echo=FALSE>>=
\r
269 for(i in c("latex", "html")) {
\r
270 outFileName <- paste("xtable.", ifelse(i=="latex", "tex", i), sep = "")
\r
271 print(xtable(lm.D9), type = i, file = outFileName, append = TRUE,
\r
272 latex.environments = NULL)
\r
273 print(xtable(lm.D9), type = i, file = outFileName, append = TRUE,
\r
274 latex.environments = "")
\r
275 print(xtable(lm.D9), type = i, file = outFileName, append = TRUE,
\r
276 latex.environments = "center")
\r
277 print(xtable(anova(glm.D93, test = "Chisq")),
\r
278 type = i, file = outFileName,
\r
280 print(xtable(anova(glm.D93)), hline.after = c(1),
\r
281 size = "small", type = i,
\r
282 file = outFileName, append = TRUE)
\r
283 # print(xtable(pr2), type = i, file = outFileName, append = TRUE)
\r
288 \section{Helper functions for formatting}
\r
289 \label{sec:helperfns}
\r
290 The functions \code{xalign}, \code{xdigits}, and \code{xdisplay} are
\r
291 useful for formatting tables in a sensible way.
\r
294 dat <- mtcars[1:3, 1:6]
\r
297 Consider the output produced by the default formatting.
\r
304 In a \LaTeX\ document this appears as follows.
\r
306 <<currentresult, echo = FALSE, results = 'asis'>>=
\r
310 Now change the default alignment, digits and display using helper functions
\r
311 \texttt{xalign}, \texttt{xdigits}, and \texttt{xdisplay}.
\r
315 align(x) <- xalign(x)
\r
316 digits(x) <- xdigits(x)
\r
317 display(x) <- xdisplay(x)
\r
321 This produces a better format as shown below.
\r
323 <<proposedresult, echo = FALSE, results = 'asis'>>=
\r
329 \section{Sanitization}
\r
331 insane <- data.frame(Name = c("Ampersand","Greater than","Less than",
\r
332 "Underscore","Per cent","Dollar",
\r
333 "Backslash","Hash","Caret","Tilde",
\r
334 "Left brace","Right brace"),
\r
335 Character = I(c("&",">","<","_","%","$",
\r
336 "\\","#","^","~","{","}")))
\r
337 colnames(insane)[2] <- paste(insane[, 2], collapse = "")
\r
340 <<pxti,results='asis'>>=
\r
341 print( xtable(insane), floating = FALSE)
\r
345 Sometimes you might want to have your own sanitization function
\r
347 wanttex <- xtable(data.frame(label =
\r
348 paste("Value_is $10^{-",1:3,"}$", sep = "")))
\r
350 <<results='asis'>>=
\r
352 sanitize.text.function =
\r
353 function(str)gsub("_", "\\_", str, fixed = TRUE))
\r
356 \subsection{Markup in tables}
\r
358 Markup can be included in tables, including in column and row names, by using
\r
359 a custom \code{sanitize.text.function()}:
\r
362 mat <- round(matrix(c(0.9, 0.89, 200, 0.045, 2.0), c(1, 5)), 4)
\r
363 rownames(mat) <- "$y_{t-1}$"
\r
364 colnames(mat) <- c("$R^2$", "$\\bar{R}^2$", "F-stat", "S.E.E", "DW")
\r
367 <<results='asis'>>=
\r
368 print(mat, sanitize.text.function = function(x){x})
\r
371 % By David Dahl to demonstrate contribution from David Whitting, 2007-10-09.
\r
372 You can also have sanitize functions that are specific to column or
\r
373 row names. In the table below, the row name is not sanitized but
\r
374 column names and table elements are:
\r
376 money <- matrix(c("$1,000","$900","$100"), ncol = 3,
\r
377 dimnames = list("$\\alpha$",
\r
378 c("Income (US$)","Expenses (US$)",
\r
381 <<results='asis'>>=
\r
382 print(xtable(money), sanitize.rownames.function = function(x) {x})
\r
385 \section{Format examples}
\r
386 \subsection{Adding a centering environment }
\r
387 <<results='asis'>>=
\r
388 print(xtable(lm.D9, caption = "\\tt latex.environments = NULL"),
\r
389 latex.environments = NULL)
\r
390 print(xtable(lm.D9, caption = "\\tt latex.environments = \"\""),
\r
391 latex.environments = "")
\r
392 print(xtable(lm.D9, caption = "\\tt latex.environments = \"center\""),
\r
393 latex.environments = "center")
\r
395 \subsection{Column alignment}
\r
398 tli.table <- xtable(tli[1:10, ])
\r
401 align(tli.table) <- rep("r", 6)
\r
403 <<results='asis'>>=
\r
404 print(tli.table, floating = FALSE)
\r
408 \textbf{\itshape Single string and column lines}
\r
410 align(tli.table) <- "|rrl|l|lr|"
\r
412 <<results='asis'>>=
\r
413 print(tli.table, floating = FALSE)
\r
415 \vspace{12pt}\textbf{\itshape Fixed width columns}
\r
417 align(tli.table) <- "|rr|lp{3cm}l|r|"
\r
419 <<results='asis'>>=
\r
420 print(tli.table, floating = FALSE)
\r
423 \subsection{Significant digits}
\r
426 Specify with a single argument
\r
428 digits(tli.table) <- 3
\r
430 <<results='asis'>>=
\r
431 print(tli.table, floating = FALSE)
\r
436 or one for each column, counting the row names,
\r
438 digits(tli.table) <- 1:(ncol(tli)+1)
\r
440 <<results='asis'>>=
\r
441 print(tli.table, floating = FALSE)
\r
445 or as a full matrix
\r
447 digits(tli.table) <- matrix( 0:4, nrow = 10, ncol = ncol(tli)+1 )
\r
449 <<results='asis'>>=
\r
450 print(tli.table, floating = FALSE)
\r
453 \subsection{Suppress row names}
\r
454 <<results='asis'>>=
\r
455 print((tli.table), include.rownames = FALSE, floating = FALSE)
\r
458 \vspace{12pt} If you want a vertical line on the left, you need to
\r
459 change the \code{align} attribute.
\r
461 align(tli.table) <- "|r|r|lp{3cm}l|r|"
\r
463 <<results='asis'>>=
\r
464 print((tli.table), include.rownames = FALSE, floating = FALSE)
\r
467 \vspace{12pt} Revert the alignment to what is was before.
\r
469 align(tli.table) <- "|rr|lp{3cm}l|r|"
\r
472 \subsection{Suppress column names}
\r
473 <<results='asis'>>=
\r
474 print((tli.table), include.colnames = FALSE, floating = FALSE)
\r
478 Note the doubled header lines which can be suppressed with, eg,
\r
479 <<results='asis'>>=
\r
480 print(tli.table, include.colnames = FALSE, floating = FALSE,
\r
481 hline.after = c(0,nrow(tli.table)))
\r
484 \subsection{Suppress row and column names}
\r
485 <<results='asis'>>=
\r
486 print((tli.table), include.colnames = FALSE, include.rownames = FALSE,
\r
490 \subsection{Rotate row and column names}
\r
491 The \texttt{rotate.rownames } and \texttt{rotate.colnames} arguments can be
\r
492 used to rotate the row and/or column names.
\r
494 <<results='asis'>>=
\r
495 print((tli.table), rotate.rownames = TRUE, rotate.colnames = TRUE)
\r
498 \subsection{Horizontal lines}
\r
500 \vspace{12pt}\textbf{\itshape Line locations}
\r
502 Use the \texttt{hline.after} argument to specify the position of the
\r
505 <<results='asis'>>=
\r
506 print(xtable(anova(glm.D93)), hline.after = c(1), floating = FALSE)
\r
509 \vspace{12pt}\textbf{\itshape Line styles}
\r
511 The \LaTeX package \pkg{ booktabs} can be used to specify different
\r
512 line style tags for top, middle, and bottom lines. Specifying
\r
513 \code{ booktabs = TRUE} will lead to separate tags being generated
\r
514 for the three line types.
\r
516 Insert \verb|\usepackage{booktabs}| in your \LaTeX preamble and define
\r
517 the \texttt{toprule}, \texttt{midrule}, and \texttt{bottomrule}
\r
518 tags to specify the line styles. By default, when no value is given
\r
519 for \texttt{hline.after}, a \texttt{toprule} will be drawn above the
\r
520 table, a \texttt{midrule} after the table headings and a
\r
521 \texttt{bottomrule} below the table. The width of the top and bottom
\r
522 rules can be set by supplying a value to \verb+\heavyrulewidth+. The
\r
523 width of the midrules can be set by supplying a value to
\r
524 \verb+\lightrulewidth+. The following tables have
\r
525 \verb+\heavyrulewidth = 2pt+ and \verb+\lightrulewidth = 0.5pt+, to
\r
526 ensure the difference in weight is noticeable.
\r
528 There is no support for \verb+\cmidrule+ or \verb+\specialrule+
\r
529 although they are part of the \texttt{booktabs} package.
\r
531 \heavyrulewidth = 2pt
\r
532 \lightrulewidth = 0.5pt
\r
534 <<results='asis'>>=
\r
535 print(tli.table, booktabs = TRUE, floating = FALSE)
\r
539 If \texttt{hline.after} includes $-1$, a \texttt{toprule} will be
\r
540 drawn above the table. If \texttt{hline.after} includes the number of
\r
541 rows in the table, a \texttt{bottomrule} will be drawn below the
\r
542 table. For any other values specified in \texttt{hline.after}, a
\r
543 \texttt{midrule} will be drawn after that line of the table.
\r
545 The next table has more than one \texttt{midrule}.
\r
548 bktbs <- xtable(matrix(1:10, ncol = 2))
\r
549 hlines <- c(-1,0,1,nrow(bktbs))
\r
551 This command produces the required table.
\r
552 <<results='asis'>>=
\r
553 print(bktbs, booktabs = TRUE, hline.after = hlines, floating = FALSE)
\r
557 \subsection{Table-level LaTeX}
\r
558 <<results='asis'>>=
\r
559 print(xtable(anova(glm.D93)), size = "small", floating = FALSE)
\r
563 \subsection{Long tables}
\r
564 Remember to insert \verb|\usepackage{longtable}| in your \LaTeX preamble.
\r
568 ## Demonstration of longtable support.
\r
569 x <- matrix(rnorm(1000), ncol = 10)
\r
570 x.big <- xtable(x, label = 'tabbig',
\r
571 caption = 'Example of \\code{longtable} spanning several pages')
\r
573 <<results='asis'>>=
\r
574 print(x.big, tabular.environment = 'longtable', floating = FALSE)
\r
578 %% The column name alignment is off in the following example.
\r
579 %% It needs some revision before exposing it. - CR, 7/2/2012
\r
582 %\vspace{12pt}\textbf{\itshape Long tables with the header on each page}
\r
584 %The \texttt{add.to.row} argument can be used to display the header
\r
585 %for a long table on each page, and to add a "continued" footer
\r
586 %on all pages except the last page.
\r
590 %x<-matrix(rnorm(1000), ncol = 10)
\r
592 %addtorow$pos<-list()
\r
593 %addtorow$pos[[1]]<-c(0)
\r
594 %addtorow$command<-c(paste(
\r
598 % " {\\footnotesize Continued on next page} \n",
\r
600 % " \\endlastfoot \n", sep = ""))
\r
601 %x.big2 <- xtable(x, label = "tabbig2",
\r
602 % caption = "Example of longtable with the header on each page")
\r
603 %print(x.big2, tabular.environment = "longtable", floating = FALSE,
\r
604 %include.rownames = FALSE, add.to.row = addtorow, hline.after = c(-1) )
\r
607 \subsection{Sideways tables}
\r
608 Remember to insert \verb|\usepackage{rotating}| in your LaTeX
\r
609 preamble. Sideways tables can't be forced in place with the `H'
\r
610 specifier, but you can use the \verb|\clearpage| command to get them
\r
615 x.small <- xtable(x, label = 'tabsmall', caption = 'A sideways table')
\r
618 <<results='asis'>>=
\r
619 print(x.small, floating.environment = 'sidewaystable')
\r
623 \subsection{Rescaled tables}
\r
624 Specify a \texttt{scalebox} value to rescale the table.
\r
628 x.rescale <- xtable(x, label = 'tabrescaled', caption = 'A rescaled table')
\r
631 <<results='asis'>>=
\r
632 print(x.rescale, scalebox = 0.7)
\r
635 \subsection{Table Width}
\r
636 The \texttt{tabularx} tabular environment provides more alignment options,
\r
637 and has a \texttt{width} argument to specify the table width.
\r
639 Remember to insert \verb|\usepackage{tabularx}| in your \LaTeX\ preamble.
\r
642 df.width <- data.frame(
\r
643 "label 1 with much more text than is needed" = c("item 1", "A"),
\r
644 "label 2 is also very long" = c("item 2","B"),
\r
645 "label 3" = c("item 3","C"),
\r
646 "label 4" = c("item 4 but again with too much text","D"),
\r
647 check.names = FALSE)
\r
649 x.width <- xtable(df.width,
\r
650 caption = "Using the 'tabularx' environment")
\r
651 align(x.width) <- "|l|X|X|l|X|"
\r
654 <<results='asis'>>=
\r
655 print(x.width, tabular.environment = "tabularx",
\r
656 width = "\\textwidth")
\r
659 \section{Suppressing Printing}
\r
660 By default the \texttt{print} method will print the LaTeX or HTML to standard
\r
661 output and also return the character strings invisibly. The printing to
\r
662 standard output can be suppressed by specifying \texttt{print.results = FALSE}.
\r
665 x.out <- print(tli.table, print.results = FALSE)
\r
668 Formatted output can also be captured without printing with the
\r
669 \texttt{toLatex} method. This function returns an object of class
\r
673 x.ltx <- toLatex(tli.table)
\r
678 \section{Acknowledgements}
\r
679 Most of the examples in this gallery are taken from the \texttt{xtable}
\r
681 \section{R Session information}
\r
682 <<results='asis'>>=
\r
683 toLatex(sessionInfo())
\r