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