]> git.donarmstrong.com Git - xtable.git/blob - pkg/vignettes/xtableGallery.Rnw
Vignette: combine chunks, describe models, simple booktabs and tabularx
[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, nojss]{jss}\r
9 \usepackage{booktabs}\r
10 \usepackage{longtable}\r
11 \usepackage{rotating}\r
12 \usepackage{tabularx}\r
13 \title{The xtable Gallery}\r
14 \author{Jonathan Swinton and others\\<jonathan@swintons.net>}\r
15 \Abstract{This document gives a gallery of tables which can be made by using the\r
16   \texttt{xtable} package to create \LaTeX\ output. It doubles as a regression\r
17   check for the package.}\r
18 \Keywords{Reproducible research, \LaTeX}\r
19 \Shorttitle{\pkg{xtable} Gallery} %% JSS header\r
20 \Address{Jonathan Swinton\\E-mail: \email{jonathan@swintons.net}} %% JSS last pg\r
21 \newcommand\p{\vspace{2ex}}\r
22 \begin{document}\r
23 \r
24 <<include=FALSE>>=\r
25 library(knitr)\r
26 opts_chunk$set(fig.path='figdir/fig', debug=TRUE, echo=TRUE)\r
27 @\r
28 \r
29 \section{Gallery}\r
30 \subsection{Data frame}\r
31 <<results='asis'>>=\r
32 library(xtable)\r
33 options(xtable.floating = FALSE)\r
34 data(tli)\r
35 xtable(tli[1:10, ])\r
36 @\r
37 \r
38 \newpage\r
39 \r
40 \subsection{Matrix}\r
41 <<results='asis'>>=\r
42 design.matrix <- model.matrix(~ sex*grade, data = tli[1:10, ])\r
43 xtable(design.matrix)\r
44 @\r
45 \r
46 \subsection{aov}\r
47 <<results='asis'>>=\r
48 fm1 <- aov(tlimth ~ sex + ethnicty + grade + disadvg, data = tli)\r
49 xtable(fm1)\r
50 @\r
51 \r
52 \subsection{lm}\r
53 <<results='asis'>>=\r
54 fm2 <- lm(tlimth ~ sex*ethnicty, data = tli)\r
55 xtable(fm2)\r
56 @\r
57 \r
58 \p\textbf{\itshape Anova table (one model)}\r
59 <<results='asis'>>=\r
60 xtable(anova(fm2))\r
61 @\r
62 \r
63 \p\textbf{\itshape Anova table (two models)}\r
64 <<results='asis'>>=\r
65 fm2b <- lm(tlimth ~ ethnicty, data = tli)\r
66 xtable(anova(fm2b, fm2))\r
67 @\r
68 \r
69 \subsection{glm}\r
70 <<results='asis'>>=\r
71 fm3 <- glm(disadvg ~ ethnicty*grade, data = tli, family = binomial)\r
72 xtable(fm3)\r
73 @\r
74 \r
75 \p\textbf{\itshape Anova table}\r
76 <<results='asis'>>=\r
77 xtable(anova(fm3))\r
78 @\r
79 \r
80 \subsection{More aov}\r
81 <<results='asis'>>=\r
82 ## Venables and Ripley (1997, p. 210)\r
83 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
84 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
85 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
86 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
87            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
88 npk <- data.frame(block = gl(6,4), N = factor(N), P = factor(P),\r
89                   K = factor(K), yield = yield)\r
90 npk.aov <- aov(yield ~ block + N*P*K, npk)\r
91 xtable(npk.aov)\r
92 @\r
93 \r
94 \p\textbf{\itshape Anova table}\r
95 <<results='asis'>>=\r
96 xtable(anova(npk.aov))\r
97 @\r
98 \r
99 \p\textbf{\itshape Summary table}\r
100 <<results='asis'>>=\r
101 xtable(summary(npk.aov))\r
102 @\r
103 \r
104 <<results='asis'>>=\r
105 ## Alternative multistratum model\r
106 op <- options(contrasts = c("contr.helmert", "contr.treatment"))\r
107 npk.aovE <- aov(yield ~  N*P*K + Error(block), npk)\r
108 options(op)\r
109 xtable(npk.aovE)\r
110 @\r
111 \r
112 <<results='asis'>>=\r
113 xtable(summary(npk.aovE))\r
114 @\r
115 \r
116 \subsection{More lm}\r
117 <<results='asis'>>=\r
118 ## Dobson (1990, p. 9) plant weight data\r
119 ctl <- c(4.17,5.58,5.18,6.11,4.50,4.61,5.17,4.53,5.33,5.14)\r
120 trt <- c(4.81,4.17,4.41,3.59,5.87,3.83,6.03,4.89,4.32,4.69)\r
121 group <- gl(2,10,20, labels = c("Ctl","Trt"))\r
122 weight <- c(ctl, trt)\r
123 lm.D9 <- lm(weight ~ group)\r
124 xtable(lm.D9)\r
125 @\r
126 \r
127 <<results='asis'>>=\r
128 xtable(anova(lm.D9))\r
129 @\r
130 \r
131 \subsection{More glm}\r
132 <<results='asis'>>=\r
133 ## Dobson (1990, p. 93) randomized controlled trial\r
134 counts <- c(18,17,15,20,10,20,25,13,12)\r
135 outcome <- gl(3,1,9)\r
136 treatment <- gl(3,3)\r
137 d.AD <- data.frame(treatment, outcome, counts)\r
138 glm.D93 <- glm(counts ~ outcome + treatment, family = poisson)\r
139 xtable(glm.D93, align = "r|llrc")\r
140 @\r
141 \r
142 \subsection{prcomp}\r
143 <<results='asis'>>=\r
144 pr1 <- prcomp(USArrests)\r
145 xtable(pr1)\r
146 @\r
147 \r
148 <<results='asis'>>=\r
149 xtable(summary(pr1))\r
150 @\r
151 \r
152 <<include=FALSE>>=\r
153 # pr2 <- princomp(USArrests)\r
154 # xtable(pr2)\r
155 @\r
156 \r
157 \subsection{Time series}\r
158 <<results='asis'>>=\r
159 temp.ts <- ts(cumsum(1 + round(rnorm(100), 0)),\r
160               start = c(1954, 7), frequency = 12)\r
161 temp.table <- xtable(temp.ts, digits = 0)\r
162 caption(temp.table) <- "Time series example"\r
163 print(temp.table, floating = TRUE)\r
164 @\r
165 \r
166 <<include=FALSE>>=\r
167 # ## Demonstrate saving to file\r
168 # for(i in c("latex", "html")) {\r
169 #   outFileName <- paste("xtable.", ifelse(i=="latex", "tex", i), sep = "")\r
170 #   print(xtable(lm.D9), type = i, file = outFileName, append = TRUE,\r
171 #         latex.environments = NULL)\r
172 #   print(xtable(lm.D9), type = i, file = outFileName, append = TRUE,\r
173 #         latex.environments = "")\r
174 #   print(xtable(lm.D9), type = i, file = outFileName, append = TRUE,\r
175 #         latex.environments = "center")\r
176 #   print(xtable(anova(glm.D93, test = "Chisq")),\r
177 #         type = i, file = outFileName,\r
178 #         append = TRUE)\r
179 #   print(xtable(anova(glm.D93)), hline.after = c(1),\r
180 #         size = "small", type = i,\r
181 #         file = outFileName, append = TRUE)\r
182 #   # print(xtable(pr2), type = i, file = outFileName, append = TRUE)\r
183 # }\r
184 @\r
185 \r
186 \section{Helper functions for formatting}\r
187 The functions \code{xalign}, \code{xdigits}, and \code{xdisplay} are useful for\r
188 formatting tables in a sensible way. Consider the output produced by the default\r
189 formatting.\r
190 \r
191 <<results='asis'>>=\r
192 dat <- mtcars[1:3, 1:6]\r
193 x <- xtable(dat)\r
194 x\r
195 @\r
196 \r
197 \p\r
198 Now change the default alignment, digits and display using helper functions\r
199 \code{xalign}, \code{xdigits}, and \code{xdisplay}. This produces a better\r
200 format as shown below.\r
201 \r
202 <<results='asis'>>=\r
203 align(x) <- xalign(x)\r
204 digits(x) <- xdigits(x)\r
205 display(x) <- xdisplay(x)\r
206 x\r
207 @\r
208 \r
209 \section{Sanitization}\r
210 <<results='asis'>>=\r
211 insane <- data.frame(Name = c("Ampersand","Greater than","Less than",\r
212                             "Underscore","Per cent","Dollar",\r
213                             "Backslash","Hash","Caret","Tilde",\r
214                             "Left brace","Right brace"),\r
215                      Character = I(c("&",">","<","_","%","$",\r
216                                      "\\","#","^","~","{","}")))\r
217 colnames(insane)[2] <- paste(insane[, 2], collapse = "")\r
218 xtable(insane)\r
219 @\r
220 \r
221 \p\r
222 Sometimes you might want to have your own sanitization function.\r
223 \r
224 <<results='asis'>>=\r
225 wanttex <- xtable(data.frame(label =\r
226                              paste("Value_is $10^{-",1:3,"}$", sep = "")))\r
227 print(wanttex, sanitize.text.function =\r
228       function(str) gsub("_", "\\_", str, fixed = TRUE))\r
229 @\r
230 \r
231 \subsection{Markup in tables}\r
232 Markup can be included in tables, including in column and row names, by using\r
233 a custom \code{sanitize.text.function}.\r
234 \r
235 <<results='asis'>>=\r
236 mat <- round(matrix(c(0.9, 0.89, 200, 0.045, 2.0), c(1, 5)), 4)\r
237 rownames(mat) <- "$y_{t-1}$"\r
238 colnames(mat) <- c("$R^2$", "$\\bar{R}^2$", "F-stat", "S.E.E", "DW")\r
239 mat <- xtable(mat)\r
240 print(mat, sanitize.text.function = function(x) {x})\r
241 @\r
242 \r
243 % By David Dahl to demonstrate contribution from David Whitting, 2007-10-09.\r
244 \p\r
245 You can also have sanitize functions that are specific to column or\r
246 row names.  In the table below, the row name is not sanitized but\r
247 column names and table elements are.\r
248 \r
249 <<results='asis'>>=\r
250 money <- matrix(c("$1,000","$900","$100"), ncol = 3,\r
251                 dimnames = list("$\\alpha$",\r
252                                 c("Income (US$)","Expenses (US$)",\r
253                                   "Profit (US$)")))\r
254 print(xtable(money), sanitize.rownames.function = function(x) {x})\r
255 @\r
256 \r
257 \section{Format examples}\r
258 \subsection{Adding a centering environment}\r
259 <<results='asis'>>=\r
260 print(xtable(lm.D9, caption = "\\tt latex.environments = NULL"),\r
261       floating = TRUE, latex.environments = NULL)\r
262 print(xtable(lm.D9, caption = "\\tt latex.environments = \"\""),\r
263       floating = TRUE, latex.environments = "")\r
264 print(xtable(lm.D9, caption = "\\tt latex.environments = \"center\""),\r
265       floating = TRUE, latex.environments = "center")\r
266 @\r
267 \r
268 \subsection{Column alignment}\r
269 <<results='asis'>>=\r
270 tli.table <- xtable(tli[1:10, ])\r
271 align(tli.table) <- rep("r", 6)\r
272 tli.table\r
273 @\r
274 \r
275 \p\textbf{\itshape Left aligned strings with column lines}\r
276 <<results='asis'>>=\r
277 align(tli.table) <- "|rrl|l|lr|"\r
278 tli.table\r
279 @\r
280 \r
281 \p\textbf{\itshape Fixed width columns}\r
282 <<results='asis'>>=\r
283 align(tli.table) <- "|rr|lp{3cm}l|r|"\r
284 tli.table\r
285 @\r
286 \r
287 \subsection{Number of digits}\r
288 One number for all columns,\r
289 <<results='asis'>>=\r
290 display(tli.table)[c(2,6)] <- "f"\r
291 digits(tli.table) <- 3\r
292 tli.table\r
293 @\r
294 \r
295 \p\r
296 or one for each column, including the row names,\r
297 <<results='asis'>>=\r
298 digits(tli.table) <- 1:(ncol(tli)+1)\r
299 tli.table\r
300 @\r
301 \r
302 \p\r
303 or as a full matrix.\r
304 <<results='asis'>>=\r
305 digits(tli.table) <- matrix(0:4, nrow = 10, ncol = ncol(tli)+1)\r
306 tli.table\r
307 @\r
308 \r
309 \subsection{Suppress row names}\r
310 <<results='asis'>>=\r
311 tli.table <- xtable(tli[1:10, ])\r
312 print(tli.table, include.rownames = FALSE)\r
313 @\r
314 \r
315 \p\r
316 If you want a vertical line on the left, you need to change the \code{align}\r
317 attribute.\r
318 <<results='asis'>>=\r
319 align(tli.table) <- "|r|r|lp{3cm}l|r|"\r
320 print(tli.table, include.rownames = FALSE)\r
321 @\r
322 \r
323 \p\r
324 Revert the alignment to what is was before.\r
325 <<>>=\r
326 align(tli.table) <- "|rr|lp{3cm}l|r|"\r
327 @\r
328 \r
329 \subsection{Suppress column names}\r
330 <<results='asis'>>=\r
331 print(tli.table, include.colnames = FALSE)\r
332 @\r
333 \r
334 \p\r
335 Note the doubled header lines which can be suppressed.\r
336 <<results='asis'>>=\r
337 print(tli.table, include.colnames = FALSE,\r
338       hline.after = c(0,nrow(tli.table)))\r
339 @\r
340 \r
341 \subsection{Suppress row and column names}\r
342 <<results='asis'>>=\r
343 print(tli.table, include.colnames = FALSE, include.rownames = FALSE)\r
344 @\r
345 \r
346 \subsection{Rotate row and column names}\r
347 The \code{rotate.rownames} and \code{rotate.colnames} arguments can be used to\r
348 rotate the row and/or column names. This requires \verb|\usepackage{rotating}|\r
349 in the \LaTeX\ preamble.\r
350 \r
351 <<results='asis'>>=\r
352 print(tli.table, rotate.rownames = TRUE, rotate.colnames = TRUE)\r
353 @\r
354 \r
355 \subsection{Horizontal lines}\r
356 \p\textbf{\itshape Line locations}\r
357 \r
358 Use the \code{hline.after} argument to specify the position of the\r
359 horizontal lines.\r
360 \r
361 <<results='asis'>>=\r
362 print(xtable(anova(glm.D93)), hline.after = c(1))\r
363 @\r
364 \r
365 \p\textbf{\itshape Line styles}\r
366 \r
367 Specifying \code{booktabs = TRUE} will generate three line types. By default,\r
368 when no value is given for \code{hline.after}, a \verb|\toprule| will be drawn\r
369 above the table, a \verb|\midrule| after the table headings and a\r
370 \verb|\bottomrule| below the table. This requires \verb|\usepackage{booktabs}|\r
371 in the \LaTeX\ preamble.\r
372 \r
373 \p\r
374 The top and bottom rules are slightly thicker than the mid rule. The thickness\r
375 of the lines can be set via the \LaTeX\ lengths \verb|\heavyrulewidth| and\r
376 \verb|\lightrulewidth|.\r
377 \r
378 <<results='asis'>>=\r
379 tli.table <- xtable(tli[1:10, ])\r
380 print(tli.table, include.rownames = FALSE, booktabs = TRUE)\r
381 @\r
382 \r
383 \p\r
384 If \code{hline.after} includes \code{-1}, a \verb|\toprule| will be\r
385 drawn above the table. If \code{hline.after} includes the number of\r
386 rows in the table, a \verb|\bottomrule| will be drawn below the\r
387 table. For any other values specified in \code{hline.after}, a\r
388 \verb|\midrule| will be drawn after that line of the table.\r
389 \r
390 \p\r
391 The following table has more than one \verb|\midrule|.\r
392 \r
393 <<results='asis'>>=\r
394 bktbs <- xtable(matrix(1:10, ncol = 2))\r
395 hlines <- c(-1, 0, 1, nrow(bktbs))\r
396 print(bktbs, booktabs = TRUE, hline.after = hlines)\r
397 @\r
398 \r
399 \subsection{Table-level LaTeX}\r
400 <<results='asis'>>=\r
401 print(xtable(anova(glm.D93)), size = "small")\r
402 @\r
403 \r
404 \subsection{Long tables}\r
405 Requires \verb|\usepackage{longtable}| in the \LaTeX\ preamble.\r
406 \r
407 <<results='asis'>>=\r
408 x <- matrix(rnorm(1000), ncol = 10)\r
409 x.big <- xtable(x, caption = 'A \\code{longtable} spanning several pages')\r
410 print(x.big, hline.after=c(-1, 0), tabular.environment = 'longtable')\r
411 @\r
412 \r
413 %% The column name alignment is off in the following example.\r
414 %% It needs some revision before exposing it. - CR, 7/2/2012\r
415 %\r
416 %\p\textbf{\itshape Long tables with the header on each page}\r
417 %\r
418 %The \code{add.to.row} argument can be used to display the header\r
419 %for a long table on each page, and to add a "continued" footer\r
420 %on all pages except the last page.\r
421 %\r
422 %<<results=tex>>=\r
423 %library(xtable)\r
424 %x<-matrix(rnorm(1000), ncol = 10)\r
425 %addtorow<-list()\r
426 %addtorow$pos<-list()\r
427 %addtorow$pos[[1]]<-c(0)\r
428 %addtorow$command<-c(paste(\r
429 %    "\\hline \n",\r
430 %    "  \\endhead \n",\r
431 %    "  \\hline \n",\r
432 %    "  {\\footnotesize Continued on next page} \n",\r
433 %    "  \\endfoot \n",\r
434 %    "  \\endlastfoot \n", sep = ""))\r
435 %x.big2 <- xtable(x, label = "tabbig2",\r
436 %    caption = "Example of longtable with the header on each page")\r
437 %print(x.big2, tabular.environment = "longtable",\r
438 %include.rownames = FALSE, add.to.row = addtorow, hline.after = c(-1))\r
439 %@\r
440 \r
441 \subsection{Sideways tables}\r
442 Requires \verb|\usepackage{rotating}| in the LaTeX\r
443 preamble.  Sideways tables can't be forced in place with the \code{[H]}\r
444 specifier, but you can use the \verb|\clearpage| command to get them\r
445 fairly nearby.\r
446 \r
447 <<results='asis'>>=\r
448 x <- x[1:30, ]\r
449 x.small <- xtable(x, label = 'tabsmall', caption = 'A sideways table')\r
450 print(x.small, floating = TRUE, floating.environment = 'sidewaystable')\r
451 @\r
452 \clearpage\r
453 \r
454 \subsection{Rescaled tables}\r
455 Specify a \code{scalebox} value to rescale the table.\r
456 <<results='asis'>>=\r
457 x <- x[1:20, ]\r
458 x.rescale <- xtable(x)\r
459 print(x.rescale, scalebox = 0.7)\r
460 @\r
461 \r
462 \subsection{Table width}\r
463 The \code{tabularx} environment is for typesetting tables whose overall width is\r
464 fixed. The column alignment code \code{X} denotes columns that will be stretched\r
465 to achieve the desired table width. Requires \verb|\usepackage{tabularx}| in the\r
466 \LaTeX\ preamble.\r
467 \r
468 <<results='asis'>>=\r
469 df.width <- data.frame(One = c("item 1", "A"), Two = c("item 2", "B"),\r
470                        Three = c("item 3", "C"), Four = c("item 4", "D"))\r
471 x.width <- xtable(df.width)\r
472 align(x.width) <- "|l|X|l|l|l|"\r
473 print(x.width, tabular.environment = "tabularx", width = "\\textwidth")\r
474 @\r
475 \r
476 \section{Suppressing printing}\r
477 By default the \code{print} method will print the \LaTeX\ or HTML to standard\r
478 output and also return the character strings invisibly.  The printing to\r
479 standard output can be suppressed by specifying \code{print.results = FALSE}.\r
480 \r
481 <<>>=\r
482 x.out <- print(tli.table, print.results = FALSE)\r
483 @\r
484 \r
485 Formatted output can also be captured without printing with the\r
486 \code{toLatex} method.  This function returns an object of class\r
487 \code{"Latex"}.\r
488 \r
489 <<>>=\r
490 x.ltx <- toLatex(tli.table)\r
491 class(x.ltx)\r
492 x.ltx\r
493 @\r
494 \r
495 \section{Acknowledgements}\r
496 Most of the examples in this gallery are taken from the \code{xtable}\r
497 documentation.\r
498 \r
499 \section{R session information}\r
500 <<results='asis'>>=\r
501 toLatex(sessionInfo())\r
502 @\r
503 \r
504 \end{document}\r