1 %\VignetteIndexEntry{xtable Gallery}
\r
2 %\VignetteDepends{xtable}
\r
3 %\VignetteKeywords{LaTeX, HTML, table}
\r
4 %\VignettePackage{xtable}
\r
6 % \VignetteEngine{knitr::knitr}
\r
7 %**************************************************************************
\r
8 \documentclass{article}
\r
9 \usepackage[a4paper,height=24cm]{geometry} % geometry first
\r
11 \usepackage{booktabs}
\r
12 \usepackage{longtable}
\r
13 \usepackage{parskip}
\r
14 \usepackage{rotating}
\r
15 \usepackage{tabularx}
\r
16 \usepackage{titlesec}
\r
17 \usepackage{hyperref} % hyperref last
\r
18 \titleformat\subsubsection{\bfseries\itshape}{}{0pt}{}
\r
19 \newcommand\p{\vspace{2ex}}
\r
20 \newcommand\code[1]{\texttt{#1}}
\r
21 \newcommand\pkg[1]{\textbf{#1}}
\r
22 \setcounter{tocdepth}{2}
\r
25 \title{The \pkg{xtable} Gallery}
\r
26 \author{Jonathan Swinton and others}
\r
33 \section{Introduction}
\r
34 This document gives a gallery of tables which can be made using the
\r
35 \pkg{xtable} package to create \LaTeX\ output. It doubles as a
\r
36 regression check for the package.
\r
40 opts_chunk$set(fig.path='figdir/fig', debug=TRUE, echo=TRUE)
\r
44 The first step is to load the package and set an option for this document.
\r
47 options(xtable.floating = FALSE)
\r
48 options(xtable.timestamp = "")
\r
52 \subsection{Data frame}
\r
60 design.matrix <- model.matrix(~ sex*grade, data = tli[1:10, ])
\r
61 xtable(design.matrix, digits = 0)
\r
67 fm1 <- aov(tlimth ~ sex + ethnicty + grade + disadvg, data = tli)
\r
73 fm2 <- lm(tlimth ~ sex*ethnicty, data = tli)
\r
77 \subsubsection{Anova table (one model)}
\r
82 \subsubsection{Anova table (two models)}
\r
84 fm2b <- lm(tlimth ~ ethnicty, data = tli)
\r
85 xtable(anova(fm2b, fm2))
\r
88 \subsubsection{Anova list}
\r
92 A <- factor(c(0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,
\r
93 0,1,0,1,0,1,0,1,0,1,0,1))
\r
94 B <- factor(c(0,0,1,1,0,0,1,1,0,1,0,1,1,0,1,0,0,0,1,1,
\r
95 0,0,1,1,0,0,1,1,0,0,1,1))
\r
96 C <- factor(c(0,1,1,0,1,0,0,1,0,0,1,1,0,0,1,1,0,1,0,1,
\r
97 1,0,1,0,0,0,1,1,1,1,0,0))
\r
98 Yield <- c(101, 373, 398, 291, 312, 106, 265, 450, 106, 306, 324, 449,
\r
99 272, 89, 407, 338, 87, 324, 279, 471, 323, 128, 423, 334,
\r
100 131, 103, 445, 437, 324, 361, 302, 272)
\r
101 aovdat <- data.frame(Block, A, B, C, Yield)
\r
103 old <- getOption("contrasts")
\r
104 options(contrasts = c("contr.helmert", "contr.poly"))
\r
105 (fit <- aov(Yield ~ A*B*C + Error(Block), data = aovdat))
\r
108 options(contrasts = old)
\r
113 <<xtableaovlist, results='asis'>>=
\r
120 <<results='asis'>>=
\r
121 fm3 <- glm(disadvg ~ ethnicty*grade, data = tli, family = binomial)
\r
125 \subsubsection{Analysis of deviance}
\r
126 <<results='asis'>>=
\r
130 \subsection{prcomp}
\r
131 <<results='asis'>>=
\r
132 pr1 <- prcomp(USArrests)
\r
137 <<results='asis'>>=
\r
138 xtable(summary(pr1))
\r
142 # pr2 <- princomp(USArrests)
\r
148 \subsection{Time series}
\r
149 <<results='asis'>>=
\r
150 temp.ts <- ts(cumsum(1 + round(rnorm(100), 0)),
\r
151 start = c(1954, 7), frequency = 12)
\r
152 temp.table <- xtable(temp.ts, digits = 0)
\r
156 \subsection{Flat tables}
\r
157 \label{sec:flat-tables}
\r
159 See the \textbf{Details} section of the help for \code{ftable} for a
\r
160 description of these tables, which are flat versions of
\r
161 multi-dimensional contingency tables. They require special methods to
\r
162 enable them to be printed using \pkg{xtable}
\r
167 mtcars$cyl <- factor(mtcars$cyl, levels = c("4","6","8"),
\r
168 labels = c("four","six","eight"))
\r
169 tbl <- ftable(mtcars$cyl, mtcars$vs, mtcars$am, mtcars$gear,
\r
170 row.vars = c(2, 4),
\r
171 dnn = c("Cylinders", "V/S", "Transmission", "Gears"))
\r
175 Here is the \LaTeX{} produced:
\r
178 xftbl <- xtableFtable(tbl, method = "compact")
\r
179 print.xtableFtable(xftbl, booktabs = TRUE)
\r
182 And here is a basic flat table:
\r
184 <<ftable1, results = 'asis'>>=
\r
185 xftbl <- xtableFtable(tbl)
\r
186 print.xtableFtable(xftbl)
\r
189 This illustrates the \code{method} argument:
\r
191 <<ftable2, results = 'asis'>>=
\r
192 xftbl <- xtableFtable(tbl, method = "col.compact")
\r
193 print.xtableFtable(xftbl, rotate.rownames = TRUE)
\r
196 Booktabs is incompatible with vertical lines in tables, so the
\r
197 vertical dividing line is removed.
\r
199 <<ftable3, results = 'asis'>>=
\r
200 xftbl <- xtableFtable(tbl, method = "compact")
\r
201 print.xtableFtable(xftbl, booktabs = TRUE)
\r
205 Row and column variable names can be formatted specially using
\r
206 sanitization, and row and column variable names and labels can be
\r
209 If special formatting is required for row and column labels, that can
\r
210 be done as a workaround by redefining the data and associated labels.
\r
212 <<ftable4, results = 'asis'>>=
\r
213 italic <- function(x){
\r
214 paste0('{\\emph{', x, '}}')
\r
216 mtcars$cyl <- factor(mtcars$cyl, levels = c("four","six","eight"),
\r
217 labels = c("four",italic("six"),"eight"))
\r
218 large <- function(x){
\r
219 paste0('{\\Large ', x, '}')
\r
221 bold <- function(x){
\r
222 paste0('{\\bfseries ', x, '}')
\r
224 tbl <- ftable(mtcars$cyl, mtcars$vs, mtcars$am, mtcars$gear,
\r
225 row.vars = c(2, 4),
\r
226 dnn = c("Cylinders", "V/S", "Transmission", "Gears"))
\r
227 xftbl <- xtableFtable(tbl, method = "row.compact")
\r
228 print.xtableFtable(xftbl,
\r
229 sanitize.rownames.function = large,
\r
230 sanitize.colnames.function = bold,
\r
231 rotate.colnames = TRUE,
\r
232 rotate.rownames = TRUE)
\r
240 # ## Demonstrate saving to file
\r
241 # for(i in c("latex", "html")) {
\r
242 # outFileName <- paste("xtable.", ifelse(i=="latex", "tex", i), sep = "")
\r
243 # print(xtable(lm.D9), type = i, file = outFileName, append = TRUE,
\r
244 # latex.environments = NULL)
\r
245 # print(xtable(lm.D9), type = i, file = outFileName, append = TRUE,
\r
246 # latex.environments = "")
\r
247 # print(xtable(lm.D9), type = i, file = outFileName, append = TRUE,
\r
248 # latex.environments = "center")
\r
249 # print(xtable(anova(glm.D93, test = "Chisq")),
\r
250 # type = i, file = outFileName,
\r
252 # print(xtable(anova(glm.D93)), hline.after = c(1),
\r
253 # size = "small", type = i,
\r
254 # file = outFileName, append = TRUE)
\r
255 # # print(xtable(pr2), type = i, file = outFileName, append = TRUE)
\r
259 \section{Automatic formatting}
\r
260 \subsection{Suggest alignment, digits, and display}
\r
261 The functions \code{xalign}, \code{xdigits}, and \code{xdisplay} are
\r
262 useful for formatting tables in a sensible way. Consider the output
\r
263 produced by the default formatting.
\r
265 <<results='asis'>>=
\r
267 dat <- mtcars[1:3, 1:6]
\r
273 Now change the default alignment, digits and display using helper functions
\r
274 \code{xalign}, \code{xdigits}, and \code{xdisplay}. This produces a better
\r
275 format as shown below.
\r
277 <<results='asis'>>=
\r
278 align(x) <- xalign(x)
\r
279 digits(x) <- xdigits(x)
\r
280 display(x) <- xdisplay(x)
\r
284 \subsection{Shorthand notation}
\r
285 For convenience, the three `autoformat' functions (\code{xalign},
\r
286 \code{xdigits}, and \code{xdisplay}) can be applied together when an
\r
287 \code{xtable} is created, using the \code{auto} argument:
\r
289 <<results='asis'>>=
\r
290 xtable(dat, auto = TRUE)
\r
294 Similarly, the \code{autoformat} function can be used to postprocess an
\r
295 existing \code{xtable}:
\r
297 <<results='asis'>>=
\r
304 \subsection{Math-Style Exponents}
\r
305 If you prefer $5 \times 10^5$ in your tables to 5e5, the
\r
306 \code{math.style.exponents} option to \code{print.xtable} is useful:
\r
308 <<results='asis'>>=
\r
309 print(xtable(data.frame(text = c("foo","bar"),
\r
310 googols = c(10e10,50e10),
\r
311 small = c(8e-24,7e-5),
\r
312 row.names = c("A","B")),
\r
313 display = c("s","s","g","g")),
\r
314 math.style.exponents = TRUE)
\r
317 this option also supports the values \code{ensuremath} which uses
\r
318 \code{\char`\\ensuremath} instead of \code{\$\$} and \code{UTF-8}
\r
319 which uses UTF-8 to approximate the \LaTeX typesetting.
\r
322 \section{Sanitization}
\r
323 <<results='asis'>>=
\r
324 insane <- data.frame(Name = c("Ampersand","Greater than","Less than",
\r
325 "Underscore","Per cent","Dollar",
\r
326 "Backslash","Hash","Caret","Tilde",
\r
327 "Left brace","Right brace"),
\r
328 Character = I(c("&",">","<","_","%","$",
\r
329 "\\","#","^","~","{","}")))
\r
330 colnames(insane)[2] <- paste(insane[, 2], collapse = "")
\r
335 Sometimes you might want to have your own sanitization function.
\r
338 <<results='asis'>>=
\r
339 wanttex <- xtable(data.frame(Column =
\r
340 paste("Value_is $10^{-",1:3,"}$", sep = "")))
\r
341 print(wanttex, sanitize.text.function =
\r
342 function(str) gsub("_", "\\_", str, fixed = TRUE))
\r
346 Sanitization can be useful in formatting column headings and row names:
\r
349 dat <- mtcars[1:3, 1:6]
\r
350 large <- function(x){
\r
351 paste0('{\\Large{\\bfseries ', x, '}}')
\r
353 italic <- function(x){
\r
354 paste0('{\\emph{ ', x, '}}')
\r
358 <<sanitize4, results = 'asis'>>=
\r
360 sanitize.rownames.function = italic,
\r
361 sanitize.colnames.function = large,
\r
369 \subsection{Markup in tables}
\r
370 Markup can be included in tables, including in column and row names,
\r
371 by using a custom \code{sanitize.text.function}.
\r
373 <<results='asis'>>=
\r
374 mat <- round(matrix(c(0.9, 0.89, 200, 0.045, 2.0), c(1, 5)), 4)
\r
375 rownames(mat) <- "$y_{t-1}$"
\r
376 colnames(mat) <- c("$R^2$", "$\\bar{x}$", "F-stat", "S.E.E", "DW")
\r
378 print(mat, sanitize.text.function = function(x) {x})
\r
381 % By David Dahl to demonstrate contribution from David Whitting, 2007-10-09.
\r
383 You can also have sanitize functions that are specific to column or
\r
384 row names. In the table below, the row name is not sanitized but
\r
385 column names and table elements are.
\r
387 <<results='asis'>>=
\r
388 money <- matrix(c("$1,000","$900","$100"), ncol = 3,
\r
389 dimnames = list("$\\alpha$",
\r
390 c("Income (US$)","Expenses (US$)",
\r
392 print(xtable(money), sanitize.rownames.function = function(x) {x})
\r
395 \section{Format examples}
\r
396 \subsection{Adding a centering environment}
\r
397 <<results='asis'>>=
\r
398 print(xtable(anova(fm3), caption = "\\tt latex.environments = \"\""),
\r
399 floating = TRUE, latex.environments = "")
\r
400 print(xtable(anova(fm3), caption = "\\tt latex.environments = \"center\""),
\r
401 floating = TRUE, latex.environments = "center")
\r
406 \subsection{Column alignment}
\r
407 <<results='asis'>>=
\r
408 tli.table <- xtable(tli[1:10, ])
\r
409 align(tli.table) <- rep("r", 6)
\r
413 \subsubsection{Left aligned strings with column lines}
\r
414 <<results='asis'>>=
\r
415 align(tli.table) <- "|rrl|l|lr|"
\r
419 \subsubsection{Fixed width columns}
\r
420 <<results='asis'>>=
\r
421 align(tli.table) <- "|rr|lp{3cm}l|r|"
\r
427 \subsection{Number of digits}
\r
428 One number for all columns,
\r
429 <<results='asis'>>=
\r
430 display(tli.table)[c(2,6)] <- "f"
\r
431 digits(tli.table) <- 3
\r
436 or one for each column, including the row names,
\r
437 <<results='asis'>>=
\r
438 digits(tli.table) <- 1:(ncol(tli)+1)
\r
443 or as a full matrix.
\r
444 <<results='asis'>>=
\r
445 digits(tli.table) <- matrix(0:4, nrow = 10, ncol = ncol(tli)+1)
\r
451 \subsection{Suppress row/column names}
\r
452 \subsubsection{Suppress row names}
\r
453 <<results='asis'>>=
\r
454 tli.table <- xtable(tli[1:10, ])
\r
455 print(tli.table, include.rownames = FALSE)
\r
459 If you want a vertical line on the left, you need to change the \code{align}
\r
461 <<results='asis'>>=
\r
462 align(tli.table) <- "|r|r|lp{3cm}l|r|"
\r
463 print(tli.table, include.rownames = FALSE)
\r
467 Revert the alignment to what is was before.
\r
469 align(tli.table) <- "|rr|lp{3cm}l|r|"
\r
474 \subsubsection{Suppress column names}
\r
475 <<results='asis'>>=
\r
476 print(tli.table, include.colnames = FALSE)
\r
480 Note the doubled header lines which can be suppressed.
\r
481 <<results='asis'>>=
\r
482 print(tli.table, include.colnames = FALSE,
\r
483 hline.after = c(0,nrow(tli.table)))
\r
486 \subsubsection{Suppress row and column names}
\r
487 <<results='asis'>>=
\r
488 print(tli.table, include.colnames = FALSE, include.rownames = FALSE)
\r
493 \subsection{Rotate row/column names}
\r
494 The \code{rotate.rownames} and \code{rotate.colnames} arguments can be
\r
495 used to rotate the row and/or column names. This requires
\r
496 \verb|\usepackage{rotating}| in the \LaTeX\ preamble.
\r
498 <<results='asis'>>=
\r
499 print(tli.table, rotate.rownames = TRUE, rotate.colnames = TRUE)
\r
504 \subsection{Horizontal lines}
\r
505 \subsubsection{Line locations}
\r
506 Use the \code{hline.after} argument to specify the position of the
\r
509 <<results='asis'>>=
\r
510 print(xtable(anova(fm3)), hline.after = c(1))
\r
513 \subsubsection{Line styles}
\r
514 Specifying \code{booktabs = TRUE} will generate three line types. By
\r
515 default, when no value is given for \code{hline.after}, a
\r
516 \verb|\toprule| will be drawn above the table, a \verb|\midrule| after
\r
517 the table headings and a \verb|\bottomrule| below the table. This
\r
518 requires \verb|\usepackage{booktabs}| in the \LaTeX\ preamble.
\r
522 The top and bottom rules are slightly thicker than the mid rule. The
\r
523 thickness of the lines can be set via the \LaTeX\ lengths
\r
524 \verb|\heavyrulewidth| and \verb|\lightrulewidth|.
\r
526 <<results='asis'>>=
\r
527 tli.table <- xtable(tli[1:10, ])
\r
528 print(tli.table, include.rownames = FALSE, booktabs = TRUE)
\r
533 If \code{hline.after} includes \code{-1}, a \verb|\toprule| will be
\r
534 drawn above the table. If \code{hline.after} includes the number of
\r
535 rows in the table, a \verb|\bottomrule| will be drawn below the
\r
536 table. For any other values specified in \code{hline.after}, a
\r
537 \verb|\midrule| will be drawn after that line of the table.
\r
540 The following table has more than one \verb|\midrule|.
\r
542 <<results='asis'>>=
\r
543 bktbs <- xtable(matrix(1:10, ncol = 2))
\r
544 hlines <- c(-1, 0, 1, nrow(bktbs))
\r
545 print(bktbs, booktabs = TRUE, hline.after = hlines)
\r
548 \subsection{Table level commands}
\r
549 <<results='asis'>>=
\r
550 print(xtable(anova(fm3)), size = "large")
\r
554 <<results='asis'>>=
\r
555 print(xtable(anova(fm3)), size = "\\setlength{\\tabcolsep}{12pt}")
\r
558 \subsection{Long tables}
\r
559 Requires \verb|\usepackage{longtable}| in the \LaTeX\ preamble.
\r
561 <<results='asis'>>=
\r
562 x <- matrix(rnorm(1000), ncol = 10)
\r
563 x.big <- xtable(x, caption = "A \\code{longtable} spanning several pages")
\r
564 print(x.big, hline.after=c(-1, 0), tabular.environment = "longtable")
\r
567 Extra features of the \pkg{longtable} \LaTeX{} package can typically
\r
568 be activated using \code{add.to.row}, as shown below.
\r
570 <<results='asis'>>=
\r
571 add.to.row <- list(pos = list(0), command = NULL)
\r
572 command <- paste0("\\hline\n\\endhead\n",
\r
574 "\\multicolumn{", dim(x)[2] + 1, "}{l}",
\r
575 "{\\footnotesize Continued on next page}\n",
\r
578 add.to.row$command <- command
\r
579 print(x.big, hline.after=c(-1), add.to.row = add.to.row,
\r
580 tabular.environment = "longtable")
\r
586 \subsection{Use of \code{add.to.row} argument}
\r
587 The following frequency table has outer dimnames: \code{Grade3} and
\r
591 Grade3 <- c("A","B","B","A","B","C","C","D","A","B",
\r
592 "C","C","C","D","B","B","D","C","C","D")
\r
593 Grade6 <- c("A","A","A","B","B","B","B","B","C","C",
\r
594 "A","C","C","C","D","D","D","D","D","D")
\r
595 Cohort <- table(Grade3, Grade6)
\r
600 The default behavior of \code{print.xtable} is to strip outer dimnames.
\r
601 <<results='asis'>>=
\r
606 The desired column labels can be created using \code{add.to.row}, in this case
\r
607 applying two commands to ``row number zero'' while suppressing the basic column
\r
610 <<results='asis'>>=
\r
612 addtorow$pos <- list(0, 0)
\r
613 addtorow$command <- c("& \\multicolumn{4}{c}{Grade 6} \\\\\n",
\r
614 "Grade 3 & A & B & C & D \\\\\n")
\r
615 print(xtable(Cohort), add.to.row = addtorow, include.colnames = FALSE)
\r
618 \subsection{Sideways tables}
\r
619 Requires \verb|\usepackage{rotating}| in the LaTeX
\r
620 preamble. Sideways tables can't be forced in place with the \code{[H]}
\r
621 specifier, but you can use the \verb|\clearpage| command to get them
\r
624 <<results='asis'>>=
\r
626 x.side <- xtable(x, caption = "A sideways table")
\r
627 print(x.side, floating = TRUE, floating.environment = "sidewaystable")
\r
631 \subsection{Rescaled tables}
\r
632 Specify a \code{scalebox} value to rescale the table.
\r
633 <<results='asis'>>=
\r
635 x.rescale <- xtable(x)
\r
636 print(x.rescale, scalebox = 0.7)
\r
639 \subsection{Aligning fixed width columns}
\r
640 Note that using specifications such as \verb|p{2cm}| always
\r
641 produces a \textbf{left aligned} column. What if some other alignment
\r
644 This is not really a problem with \pkg{xtable} but with the formatting
\r
645 of tables with fixed width columns and different alignments using
\r
648 One solution is to use the \verb|array| package, defining new
\r
652 \newcolumntype{L}[1]{>{\raggedright\let\newline\\
\r
653 \arraybackslash\hspace{0pt}}m{#1}}
\r
654 \newcolumntype{C}[1]{>{\centering\let\newline\\
\r
655 \arraybackslash\hspace{0pt}}m{#1}}
\r
656 \newcolumntype{R}[1]{>{\raggedleft\let\newline\\
\r
657 \arraybackslash\hspace{0pt}}m{#1}}
\r
658 \newcolumntype{P}[1]{>{\raggedright\tabularxbackslash}p{#1}}
\r
661 These allow for very sophisticated cell formatting, namely
\r
662 left-aligned, centred, or right-aligned text, with recognition of line
\r
663 breaks for the first three new column types. If these lines are
\r
664 included along with \verb|\usepackage{array}|, then the following is
\r
667 \newcolumntype{L}[1]{>{\raggedright\let\newline\\
\r
668 \arraybackslash\hspace{0pt}}m{#1}}
\r
669 \newcolumntype{C}[1]{>{\centering\let\newline\\
\r
670 \arraybackslash\hspace{0pt}}m{#1}}
\r
671 \newcolumntype{R}[1]{>{\raggedleft\let\newline\\
\r
672 \arraybackslash\hspace{0pt}}m{#1}}
\r
673 \newcolumntype{P}[1]{>{\raggedright\tabularxbackslash}p{#1}}
\r
675 <<results='asis'>>=
\r
676 df <- data.frame(name = c("A","B"), right = c(1.4, 34.6),
\r
677 left = c(1.4, 34.6), text = c("txt1","txt2"))
\r
678 print(xtable(df, align = c("l", "|c", "|R{3cm}", "|L{3cm}", "| p{3cm}|")),
\r
679 floating = FALSE, include.rownames = FALSE)
\r
684 \subsection{Table width}
\r
685 The \code{tabularx} environment is for typesetting tables whose
\r
686 overall width is fixed. The column alignment code \code{X} denotes
\r
687 columns that will be stretched to achieve the desired table
\r
688 width. Requires \verb|\usepackage{tabularx}| in the \LaTeX\ preamble.
\r
690 <<results='asis'>>=
\r
691 df.width <- data.frame(One = c("item 1", "A"), Two = c("item 2", "B"),
\r
692 Three = c("item 3", "C"), Four = c("item 4", "D"))
\r
693 x.width <- xtable(df.width)
\r
694 align(x.width) <- "|l|X|l|l|l|"
\r
695 print(x.width, tabular.environment = "tabularx", width = "\\textwidth")
\r
698 \section{Suppressing printing}
\r
699 By default the \code{print} method will print the \LaTeX\ or HTML to
\r
700 standard output and also return the character strings invisibly. The
\r
701 printing to standard output can be suppressed by specifying
\r
702 \code{print.results = FALSE}.
\r
705 x.out <- print(tli.table, print.results = FALSE)
\r
708 Formatted output can also be captured without printing with the
\r
709 \code{toLatex} method. This function returns an object of class
\r
713 x.ltx <- toLatex(tli.table)
\r
721 \section{Acknowledgements}
\r
722 Most of the examples in this gallery are taken from the \pkg{xtable}
\r
723 documentation. Two examples (\code{add.to.row} and `Aligning fixed width
\r
724 columns') are from Stack Exchange.
\r
726 \section{Session information}
\r
727 <<results='asis'>>=
\r
728 toLatex(sessionInfo())
\r