]> git.donarmstrong.com Git - xtable.git/blob - pkg/vignettes/xtableGallery.Rnw
88dd00b8c94d94657c3a749d9598049a9db7908c
[xtable.git] / pkg / vignettes / xtableGallery.Rnw
1 %\VignetteIndexEntry{xtable Gallery}\r
2 %\VignetteDepends{xtable}\r
3 %\VignetteKeywords{LaTeX, HTML, table}\r
4 %\VignettePackage{xtable}\r
5 % !Rnw weave = knitr\r
6 % \VignetteEngine{knitr::knitr}\r
7 %**************************************************************************\r
8 \documentclass{article}\r
9 \usepackage[a4paper,height=24cm]{geometry}\r
10 \usepackage{parskip}\r
11 \usepackage{titlesec}\r
12 \titleformat\subsubsection{\bfseries\itshape}{}{0pt}{}\r
13 \usepackage{booktabs}\r
14 \usepackage{longtable}\r
15 \usepackage{rotating}\r
16 \usepackage{array}\r
17 \usepackage{tabularx}\r
18 \newcommand\p{\vspace{2ex}}\r
19 \setcounter{tocdepth}{2}\r
20 %% Define \code \proglang and \pkg commands\r
21 \newcommand\code[1]{\texttt{#1}}\r
22 \newcommand\pkg[1]{\textbf{#1}}\r
23 \newcommand\R{\textsf{R}}\r
24 %% url and hyperref\r
25 \usepackage[hyphens]{url}\r
26 \usepackage{hyperref}\r
27 \begin{document}\r
28 \r
29 \title{The \pkg{xtable} Gallery}\r
30 \author{Jonathan Swinton and others}\r
31 \maketitle\r
32 \r
33 \tableofcontents\r
34 \r
35 \newpage\r
36 \r
37 \section{Introduction}\r
38 \label{sec:introduction}\r
39 \r
40 This document gives a gallery of tables which can be made using the\r
41 \pkg{xtable} package to create \LaTeX\ output. It doubles as a\r
42 regression check for the package.\r
43 \r
44 <<include=FALSE>>=\r
45 library(knitr)\r
46 opts_chunk$set(fig.path='figdir/fig', debug=TRUE, echo=TRUE)\r
47 @\r
48 \r
49 The first step is to load the package and set an option for this document.\r
50 <<results='asis'>>=\r
51 library(xtable)\r
52 options(xtable.floating = FALSE)\r
53 @\r
54 \r
55 \section{Gallery}\r
56 \subsection{Data frame}\r
57 <<results='asis'>>=\r
58 data(tli)\r
59 xtable(tli[1:10, ])\r
60 @\r
61 \r
62 \subsection{Matrix}\r
63 <<results='asis'>>=\r
64 design.matrix <- model.matrix(~ sex*grade, data = tli[1:10, ])\r
65 xtable(design.matrix, digits = 0)\r
66 @\r
67 \r
68 \newpage\r
69 \subsection{aov}\r
70 <<results='asis'>>=\r
71 fm1 <- aov(tlimth ~ sex + ethnicty + grade + disadvg, data = tli)\r
72 xtable(fm1)\r
73 @\r
74 \r
75 \subsection{lm}\r
76 <<results='asis'>>=\r
77 fm2 <- lm(tlimth ~ sex*ethnicty, data = tli)\r
78 xtable(fm2)\r
79 @\r
80 \r
81 \subsubsection{Anova table (one model)}\r
82 <<results='asis'>>=\r
83 xtable(anova(fm2))\r
84 @\r
85 \r
86 \subsubsection{Anova table (two models)}\r
87 <<results='asis'>>=\r
88 fm2b <- lm(tlimth ~ ethnicty, data = tli)\r
89 xtable(anova(fm2b, fm2))\r
90 @\r
91 \r
92 \newpage\r
93 \subsection{glm}\r
94 <<results='asis'>>=\r
95 fm3 <- glm(disadvg ~ ethnicty*grade, data = tli, family = binomial)\r
96 xtable(fm3)\r
97 @\r
98 \r
99 \subsubsection{Analysis of deviance}\r
100 <<results='asis'>>=\r
101 xtable(anova(fm3))\r
102 @\r
103 \r
104 \subsection{prcomp}\r
105 <<results='asis'>>=\r
106 pr1 <- prcomp(USArrests)\r
107 xtable(pr1)\r
108 @\r
109 \r
110 \p\r
111 <<results='asis'>>=\r
112 xtable(summary(pr1))\r
113 @\r
114 \r
115 <<include=FALSE>>=\r
116 # pr2 <- princomp(USArrests)\r
117 # xtable(pr2)\r
118 @\r
119 \r
120 \subsection{Time series}\r
121 <<results='asis'>>=\r
122 temp.ts <- ts(cumsum(1 + round(rnorm(100), 0)),\r
123               start = c(1954, 7), frequency = 12)\r
124 temp.table <- xtable(temp.ts, digits = 0)\r
125 temp.table\r
126 @\r
127 \r
128 \newpage\r
129 \r
130 <<include=FALSE>>=\r
131 # ## Demonstrate saving to file\r
132 # for(i in c("latex", "html")) {\r
133 #   outFileName <- paste("xtable.", ifelse(i=="latex", "tex", i), sep = "")\r
134 #   print(xtable(lm.D9), type = i, file = outFileName, append = TRUE,\r
135 #         latex.environments = NULL)\r
136 #   print(xtable(lm.D9), type = i, file = outFileName, append = TRUE,\r
137 #         latex.environments = "")\r
138 #   print(xtable(lm.D9), type = i, file = outFileName, append = TRUE,\r
139 #         latex.environments = "center")\r
140 #   print(xtable(anova(glm.D93, test = "Chisq")),\r
141 #         type = i, file = outFileName,\r
142 #         append = TRUE)\r
143 #   print(xtable(anova(glm.D93)), hline.after = c(1),\r
144 #         size = "small", type = i,\r
145 #         file = outFileName, append = TRUE)\r
146 #   # print(xtable(pr2), type = i, file = outFileName, append = TRUE)\r
147 # }\r
148 @\r
149 \r
150 \section{Helper functions for formatting}\r
151 The functions \code{xalign}, \code{xdigits}, and \code{xdisplay} are useful for\r
152 formatting tables in a sensible way. Consider the output produced by the default\r
153 formatting.\r
154 \r
155 <<results='asis'>>=\r
156 dat <- mtcars[1:3, 1:6]\r
157 x <- xtable(dat)\r
158 x\r
159 @\r
160 \r
161 \p\r
162 Now change the default alignment, digits and display using helper functions\r
163 \code{xalign}, \code{xdigits}, and \code{xdisplay}. This produces a better\r
164 format as shown below.\r
165 \r
166 <<results='asis'>>=\r
167 align(x) <- xalign(x)\r
168 digits(x) <- xdigits(x)\r
169 display(x) <- xdisplay(x)\r
170 x\r
171 @\r
172 \r
173 \newpage\r
174 \r
175 \section{Sanitization}\r
176 <<results='asis'>>=\r
177 insane <- data.frame(Name = c("Ampersand","Greater than","Less than",\r
178                             "Underscore","Per cent","Dollar",\r
179                             "Backslash","Hash","Caret","Tilde",\r
180                             "Left brace","Right brace"),\r
181                      Character = I(c("&",">","<","_","%","$",\r
182                                      "\\","#","^","~","{","}")))\r
183 colnames(insane)[2] <- paste(insane[, 2], collapse = "")\r
184 xtable(insane)\r
185 @\r
186 \r
187 \p\r
188 Sometimes you might want to have your own sanitization function.\r
189 \r
190 <<results='asis'>>=\r
191 wanttex <- xtable(data.frame(Column =\r
192                              paste("Value_is $10^{-",1:3,"}$", sep = "")))\r
193 print(wanttex, sanitize.text.function =\r
194       function(str) gsub("_", "\\_", str, fixed = TRUE))\r
195 @\r
196 \r
197 \subsection{Markup in tables}\r
198 Markup can be included in tables, including in column and row names, by using\r
199 a custom \code{sanitize.text.function}.\r
200 \r
201 <<results='asis'>>=\r
202 mat <- round(matrix(c(0.9, 0.89, 200, 0.045, 2.0), c(1, 5)), 4)\r
203 rownames(mat) <- "$y_{t-1}$"\r
204 colnames(mat) <- c("$R^2$", "$\\bar{x}$", "F-stat", "S.E.E", "DW")\r
205 mat <- xtable(mat)\r
206 print(mat, sanitize.text.function = function(x) {x})\r
207 @\r
208 \r
209 \newpage\r
210 % By David Dahl to demonstrate contribution from David Whitting, 2007-10-09.\r
211 \r
212 You can also have sanitize functions that are specific to column or\r
213 row names.  In the table below, the row name is not sanitized but\r
214 column names and table elements are.\r
215 \r
216 <<results='asis'>>=\r
217 money <- matrix(c("$1,000","$900","$100"), ncol = 3,\r
218                 dimnames = list("$\\alpha$",\r
219                                 c("Income (US$)","Expenses (US$)",\r
220                                   "Profit (US$)")))\r
221 print(xtable(money), sanitize.rownames.function = function(x) {x})\r
222 @\r
223 \r
224 \section{Format examples}\r
225 \subsection{Adding a centering environment}\r
226 <<results='asis'>>=\r
227 print(xtable(anova(fm3), caption = "\\tt latex.environments = \"\""),\r
228       floating = TRUE, latex.environments = "")\r
229 print(xtable(anova(fm3), caption = "\\tt latex.environments = \"center\""),\r
230       floating = TRUE, latex.environments = "center")\r
231 @\r
232 \r
233 \newpage\r
234 \r
235 \subsection{Column alignment}\r
236 <<results='asis'>>=\r
237 tli.table <- xtable(tli[1:10, ])\r
238 align(tli.table) <- rep("r", 6)\r
239 tli.table\r
240 @\r
241 \r
242 \subsubsection{Left aligned strings with column lines}\r
243 <<results='asis'>>=\r
244 align(tli.table) <- "|rrl|l|lr|"\r
245 tli.table\r
246 @\r
247 \r
248 \subsubsection{Fixed width columns}\r
249 <<results='asis'>>=\r
250 align(tli.table) <- "|rr|lp{3cm}l|r|"\r
251 tli.table\r
252 @\r
253 \r
254 \newpage\r
255 \r
256 \subsection{Number of digits}\r
257 One number for all columns,\r
258 <<results='asis'>>=\r
259 display(tli.table)[c(2,6)] <- "f"\r
260 digits(tli.table) <- 3\r
261 tli.table\r
262 @\r
263 \r
264 \p\r
265 or one for each column, including the row names,\r
266 <<results='asis'>>=\r
267 digits(tli.table) <- 1:(ncol(tli)+1)\r
268 tli.table\r
269 @\r
270 \r
271 \p\r
272 or as a full matrix.\r
273 <<results='asis'>>=\r
274 digits(tli.table) <- matrix(0:4, nrow = 10, ncol = ncol(tli)+1)\r
275 tli.table\r
276 @\r
277 \r
278 \newpage\r
279 \r
280 \subsection{Suppress row/column names}\r
281 \subsubsection{Suppress row names}\r
282 <<results='asis'>>=\r
283 tli.table <- xtable(tli[1:10, ])\r
284 print(tli.table, include.rownames = FALSE)\r
285 @\r
286 \r
287 \p\r
288 If you want a vertical line on the left, you need to change the \code{align}\r
289 attribute.\r
290 <<results='asis'>>=\r
291 align(tli.table) <- "|r|r|lp{3cm}l|r|"\r
292 print(tli.table, include.rownames = FALSE)\r
293 @\r
294 \r
295 \p\r
296 Revert the alignment to what is was before.\r
297 <<>>=\r
298 align(tli.table) <- "|rr|lp{3cm}l|r|"\r
299 @\r
300 \r
301 \newpage\r
302 \r
303 \subsubsection{Suppress column names}\r
304 <<results='asis'>>=\r
305 print(tli.table, include.colnames = FALSE)\r
306 @\r
307 \r
308 \p\r
309 Note the doubled header lines which can be suppressed.\r
310 <<results='asis'>>=\r
311 print(tli.table, include.colnames = FALSE,\r
312       hline.after = c(0,nrow(tli.table)))\r
313 @\r
314 \r
315 \subsubsection{Suppress row and column names}\r
316 <<results='asis'>>=\r
317 print(tli.table, include.colnames = FALSE, include.rownames = FALSE)\r
318 @\r
319 \r
320 \newpage\r
321 \r
322 \subsection{Rotate row/column names}\r
323 The \code{rotate.rownames} and \code{rotate.colnames} arguments can be used to\r
324 rotate the row and/or column names. This requires \verb|\usepackage{rotating}|\r
325 in the \LaTeX\ preamble.\r
326 \r
327 <<results='asis'>>=\r
328 print(tli.table, rotate.rownames = TRUE, rotate.colnames = TRUE)\r
329 @\r
330 \r
331 \newpage\r
332 \r
333 \subsection{Horizontal lines}\r
334 \subsubsection{Line locations}\r
335 Use the \code{hline.after} argument to specify the position of the\r
336 horizontal lines.\r
337 \r
338 <<results='asis'>>=\r
339 print(xtable(anova(fm3)), hline.after = c(1))\r
340 @\r
341 \r
342 \subsubsection{Line styles}\r
343 Specifying \code{booktabs = TRUE} will generate three line types. By default,\r
344 when no value is given for \code{hline.after}, a \verb|\toprule| will be drawn\r
345 above the table, a \verb|\midrule| after the table headings and a\r
346 \verb|\bottomrule| below the table. This requires \verb|\usepackage{booktabs}|\r
347 in the \LaTeX\ preamble.\r
348 \r
349 \p\r
350 The top and bottom rules are slightly thicker than the mid rule. The thickness\r
351 of the lines can be set via the \LaTeX\ lengths \verb|\heavyrulewidth| and\r
352 \verb|\lightrulewidth|.\r
353 \r
354 <<results='asis'>>=\r
355 tli.table <- xtable(tli[1:10, ])\r
356 print(tli.table, include.rownames = FALSE, booktabs = TRUE)\r
357 @\r
358 \r
359 \p\r
360 If \code{hline.after} includes \code{-1}, a \verb|\toprule| will be\r
361 drawn above the table. If \code{hline.after} includes the number of\r
362 rows in the table, a \verb|\bottomrule| will be drawn below the\r
363 table. For any other values specified in \code{hline.after}, a\r
364 \verb|\midrule| will be drawn after that line of the table.\r
365 \r
366 \p\r
367 The following table has more than one \verb|\midrule|.\r
368 \r
369 <<results='asis'>>=\r
370 bktbs <- xtable(matrix(1:10, ncol = 2))\r
371 hlines <- c(-1, 0, 1, nrow(bktbs))\r
372 print(bktbs, booktabs = TRUE, hline.after = hlines)\r
373 @\r
374 \r
375 \subsection{Table level commands}\r
376 <<results='asis'>>=\r
377 print(xtable(anova(fm3)), size = "large")\r
378 @\r
379 \r
380 \p\r
381 <<results='asis'>>=\r
382 print(xtable(anova(fm3)), size = "\\setlength{\\tabcolsep}{12pt}")\r
383 @\r
384 \r
385 \subsection{Long tables}\r
386 Requires \verb|\usepackage{longtable}| in the \LaTeX\ preamble.\r
387 \r
388 <<results='asis'>>=\r
389 x <- matrix(rnorm(1000), ncol = 10)\r
390 x.big <- xtable(x, caption = "A \\code{longtable} spanning several pages")\r
391 print(x.big, hline.after=c(-1, 0), tabular.environment = "longtable")\r
392 @\r
393 \r
394 %% The column name alignment is off in the following example.\r
395 %% It needs some revision before exposing it. - CR, 7/2/2012\r
396 %\r
397 %% Tried to fix this and got some of the way, but \hlines are wrong\r
398 %% and first column is too wide. - DJS 4/10/2014\r
399 %% \subsubsection{Long tables with the header on each page}\r
400 %% The \code{add.to.row} argument can be used to display the header\r
401 %% for a long table on each page, and to add a "continued" footer\r
402 %% on all pages except the last page.\r
403 \r
404 %% \newcommand{\head}[1]{\centercell{\bfseries#1}}\r
405 \r
406 %% <<results='asis'>>=\r
407 %% x <- matrix(rnorm(1000), ncol = 10)\r
408 %% hdr <-  paste(paste("\\multicolumn{1}{c}{",1:9,"} & ", collapse = ""),\r
409 %%               "\\multicolumn{1}{c}{10}\\\\")\r
410 %% addtorow <- list()\r
411 %% addtorow$pos <- list()\r
412 %% addtorow$pos[[1]] <- c(0)\r
413 %% addtorow$command <- c(paste(\r
414 %%     hdr,\r
415 %%     "  \\hline \n",\r
416 %%     "  \\endhead \n",\r
417 %%     "  \\hline \n",\r
418 %%     "  {\\footnotesize Continued on next page} \n",\r
419 %%     "  \\endfoot \n",\r
420 %%     "  \\endlastfoot \n", sep = ""))\r
421 %% x.big2 <- xtable(x, label = "tabbig2", align = "lrrrrrrrrrr",\r
422 %%                  caption = "Example of longtable with the header on each page")\r
423 %% print(x.big2, tabular.environment = "longtable",\r
424 %%       include.rownames = FALSE, include.colnames = FALSE,\r
425 %%       add.to.row = addtorow)\r
426 %% @\r
427 \r
428 \newpage\r
429 \r
430 \subsection{Use of \code{add.to.row} argument}\r
431 The following frequency table has outer dimnames: \code{Grade3} and\r
432 \code{Grade6}.\r
433 \r
434 <<>>=\r
435 Grade3 <- c("A","B","B","A","B","C","C","D","A","B",\r
436             "C","C","C","D","B","B","D","C","C","D")\r
437 Grade6 <- c("A","A","A","B","B","B","B","B","C","C",\r
438             "A","C","C","C","D","D","D","D","D","D")\r
439 Cohort <- table(Grade3, Grade6)\r
440 Cohort\r
441 @\r
442 \r
443 \p\r
444 The default behavior of \code{print.xtable} is to strip outer dimnames.\r
445 <<results='asis'>>=\r
446 xtable(Cohort)\r
447 @\r
448 \r
449 \p\r
450 The desired column labels can be created using \code{add.to.row}, in this case\r
451 applying two commands to ``row number zero'' while suppressing the basic column\r
452 names.\r
453 \r
454 <<results='asis'>>=\r
455 addtorow <- list()\r
456 addtorow$pos <- list(0, 0)\r
457 addtorow$command <- c("& \\multicolumn{4}{c}{Grade 6} \\\\\n",\r
458                       "Grade 3 & A & B & C & D \\\\\n")\r
459 print(xtable(Cohort), add.to.row = addtorow, include.colnames = FALSE)\r
460 @\r
461 \r
462 \subsection{Sideways tables}\r
463 Requires \verb|\usepackage{rotating}| in the LaTeX\r
464 preamble.  Sideways tables can't be forced in place with the \code{[H]}\r
465 specifier, but you can use the \verb|\clearpage| command to get them\r
466 fairly nearby.\r
467 \r
468 <<results='asis'>>=\r
469 x <- x[1:30, ]\r
470 x.side <- xtable(x, caption = "A sideways table")\r
471 print(x.side, floating = TRUE, floating.environment = "sidewaystable")\r
472 @\r
473 \clearpage\r
474 \r
475 \subsection{Rescaled tables}\r
476 Specify a \code{scalebox} value to rescale the table.\r
477 <<results='asis'>>=\r
478 x <- x[1:20, ]\r
479 x.rescale <- xtable(x)\r
480 print(x.rescale, scalebox = 0.7)\r
481 @\r
482 \r
483 \newpage\r
484 \r
485 \subsection{Aligning fixed width columns}\r
486 Note that using specifications such as \verb|p{2cm}| always\r
487 produces a \textbf{left aligned} column. What if some other alignment\r
488 is desired?\r
489 \r
490 This is not really a problem with \pkg{xtable} but with the formatting\r
491 of tables with fixed width columns and different alignments using\r
492 standard \LaTeX.\r
493 \r
494 One solution is to use the \verb|array| package, defining new\r
495 column formats.\r
496 \r
497 \begin{verbatim}\r
498 \newcolumntype{L}[1]{>{\raggedright\let\newline\\\r
499     \arraybackslash\hspace{0pt}}m{#1}}\r
500 \newcolumntype{C}[1]{>{\centering\let\newline\\\r
501     \arraybackslash\hspace{0pt}}m{#1}}\r
502 \newcolumntype{R}[1]{>{\raggedleft\let\newline\\\r
503     \arraybackslash\hspace{0pt}}m{#1}}\r
504 \newcolumntype{P}[1]{>{\raggedright\tabularxbackslash}p{#1}}\r
505 \end{verbatim}\r
506 \r
507 These allow for very sophisticated cell formatting, namely\r
508 left-aligned, centred, or right-aligned text, with recognition of line\r
509 breaks for the first three new column types. If these lines are\r
510 included along with \verb|\usepackage{array}|, then the following\r
511 is possible.\r
512 \r
513 \newcolumntype{L}[1]{>{\raggedright\let\newline\\\r
514     \arraybackslash\hspace{0pt}}m{#1}}\r
515 \newcolumntype{C}[1]{>{\centering\let\newline\\\r
516     \arraybackslash\hspace{0pt}}m{#1}}\r
517 \newcolumntype{R}[1]{>{\raggedleft\let\newline\\\r
518     \arraybackslash\hspace{0pt}}m{#1}}\r
519 \newcolumntype{P}[1]{>{\raggedright\tabularxbackslash}p{#1}}\r
520 \r
521 <<results='asis'>>=\r
522 df <- data.frame(name = c("A","B"), right = c(1.4, 34.6),\r
523                  left = c(1.4, 34.6), text = c("txt1","txt2"))\r
524 print(xtable(df, align = c("l", "|c", "|R{3cm}", "|L{3cm}", "| p{3cm}|")),\r
525       floating = FALSE, include.rownames = FALSE)\r
526 @\r
527 \r
528 \subsection{Table width}\r
529 The \code{tabularx} environment is for typesetting tables whose overall width is\r
530 fixed. The column alignment code \code{X} denotes columns that will be stretched\r
531 to achieve the desired table width. Requires \verb|\usepackage{tabularx}| in the\r
532 \LaTeX\ preamble.\r
533 \r
534 <<results='asis'>>=\r
535 df.width <- data.frame(One = c("item 1", "A"), Two = c("item 2", "B"),\r
536                        Three = c("item 3", "C"), Four = c("item 4", "D"))\r
537 x.width <- xtable(df.width)\r
538 align(x.width) <- "|l|X|l|l|l|"\r
539 print(x.width, tabular.environment = "tabularx", width = "\\textwidth")\r
540 @\r
541 \r
542 \newpage\r
543 \r
544 \section{Suppressing printing}\r
545 By default the \code{print} method will print the \LaTeX\ or HTML to standard\r
546 output and also return the character strings invisibly.  The printing to\r
547 standard output can be suppressed by specifying \code{print.results = FALSE}.\r
548 \r
549 <<>>=\r
550 x.out <- print(tli.table, print.results = FALSE)\r
551 @\r
552 \r
553 Formatted output can also be captured without printing with the\r
554 \code{toLatex} method.  This function returns an object of class\r
555 \code{"Latex"}.\r
556 \r
557 <<>>=\r
558 x.ltx <- toLatex(tli.table)\r
559 class(x.ltx)\r
560 x.ltx\r
561 @\r
562 \r
563 \section{Acknowledgements}\r
564 Most of the examples in this gallery are taken from the \pkg{xtable}\r
565 documentation. Two examples (\code{add.to.row} and `Aligning fixed width\r
566 columns') are from Stack Exchange.\r
567 \r
568 \section{\R\ session information}\r
569 <<results='asis'>>=\r
570 toLatex(sessionInfo())\r
571 @\r
572 \r
573 \end{document}\r