%\VignetteIndexEntry{xtable Gallery} %\VignetteDepends{xtable} %\VignetteKeywords{LaTeX, HTML, table} %\VignettePackage{xtable} % !Rnw weave = knitr % \VignetteEngine{knitr::knitr} %************************************************************************** \documentclass[article, nojss]{jss} \usepackage{booktabs} \usepackage{longtable} \usepackage{rotating} \usepackage{tabularx} \title{The xtable Gallery} \author{Jonathan Swinton and others\\} \Abstract{This document gives a gallery of tables which can be made by using the \texttt{xtable} package to create \LaTeX\ output. It doubles as a regression check for the package.} \Keywords{Reproducible research, \LaTeX} \Shorttitle{\pkg{xtable} Gallery} %% JSS header \Address{Jonathan Swinton\\E-mail: \email{jonathan@swintons.net}} %% JSS last pg \newcommand\p{\vspace{2ex}} \begin{document} <>= library(knitr) opts_chunk$set(fig.path='figdir/fig', debug=TRUE, echo=TRUE) @ \section{Gallery} \subsection{Data frame} <>= library(xtable) options(xtable.floating = FALSE) data(tli) xtable(tli[1:10, ]) @ \newpage \subsection{Matrix} <>= design.matrix <- model.matrix(~ sex*grade, data = tli[1:10, ]) xtable(design.matrix) @ \subsection{aov} <>= fm1 <- aov(tlimth ~ sex + ethnicty + grade + disadvg, data = tli) xtable(fm1) @ \subsection{lm} <>= fm2 <- lm(tlimth ~ sex*ethnicty, data = tli) xtable(fm2) @ \p\textbf{\itshape Anova table (one model)} <>= xtable(anova(fm2)) @ \p\textbf{\itshape Anova table (two models)} <>= fm2b <- lm(tlimth ~ ethnicty, data = tli) xtable(anova(fm2b, fm2)) @ \subsection{glm} <>= fm3 <- glm(disadvg ~ ethnicty*grade, data = tli, family = binomial) xtable(fm3) @ \p\textbf{\itshape Anova table} <>= xtable(anova(fm3)) @ \subsection{More aov} <>= ## Venables and Ripley (1997, p. 210) 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) 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) 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) 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, 62.0,48.8,45.5,44.2,52.0,51.5,49.8,48.8,57.2,59.0,53.2,56.0) npk <- data.frame(block = gl(6,4), N = factor(N), P = factor(P), K = factor(K), yield = yield) npk.aov <- aov(yield ~ block + N*P*K, npk) xtable(npk.aov) @ \p\textbf{\itshape Anova table} <>= xtable(anova(npk.aov)) @ \p\textbf{\itshape Summary table} <>= xtable(summary(npk.aov)) @ <>= ## Alternative multistratum model op <- options(contrasts = c("contr.helmert", "contr.treatment")) npk.aovE <- aov(yield ~ N*P*K + Error(block), npk) options(op) xtable(npk.aovE) @ <>= xtable(summary(npk.aovE)) @ \subsection{More lm} <>= ## Dobson (1990, p. 9) plant weight data ctl <- c(4.17,5.58,5.18,6.11,4.50,4.61,5.17,4.53,5.33,5.14) trt <- c(4.81,4.17,4.41,3.59,5.87,3.83,6.03,4.89,4.32,4.69) group <- gl(2,10,20, labels = c("Ctl","Trt")) weight <- c(ctl, trt) lm.D9 <- lm(weight ~ group) xtable(lm.D9) @ <>= xtable(anova(lm.D9)) @ \subsection{More glm} <>= ## Dobson (1990, p. 93) randomized controlled trial counts <- c(18,17,15,20,10,20,25,13,12) outcome <- gl(3,1,9) treatment <- gl(3,3) d.AD <- data.frame(treatment, outcome, counts) glm.D93 <- glm(counts ~ outcome + treatment, family = poisson) xtable(glm.D93, align = "r|llrc") @ \subsection{prcomp} <>= pr1 <- prcomp(USArrests) xtable(pr1) @ <>= xtable(summary(pr1)) @ <>= # pr2 <- princomp(USArrests) # xtable(pr2) @ \subsection{Time series} <>= temp.ts <- ts(cumsum(1 + round(rnorm(100), 0)), start = c(1954, 7), frequency = 12) temp.table <- xtable(temp.ts, digits = 0) caption(temp.table) <- "Time series example" print(temp.table, floating = TRUE) @ <>= # ## Demonstrate saving to file # for(i in c("latex", "html")) { # outFileName <- paste("xtable.", ifelse(i=="latex", "tex", i), sep = "") # print(xtable(lm.D9), type = i, file = outFileName, append = TRUE, # latex.environments = NULL) # print(xtable(lm.D9), type = i, file = outFileName, append = TRUE, # latex.environments = "") # print(xtable(lm.D9), type = i, file = outFileName, append = TRUE, # latex.environments = "center") # print(xtable(anova(glm.D93, test = "Chisq")), # type = i, file = outFileName, # append = TRUE) # print(xtable(anova(glm.D93)), hline.after = c(1), # size = "small", type = i, # file = outFileName, append = TRUE) # # print(xtable(pr2), type = i, file = outFileName, append = TRUE) # } @ \section{Helper functions for formatting} The functions \code{xalign}, \code{xdigits}, and \code{xdisplay} are useful for formatting tables in a sensible way. Consider the output produced by the default formatting. <>= dat <- mtcars[1:3, 1:6] x <- xtable(dat) x @ \p Now change the default alignment, digits and display using helper functions \code{xalign}, \code{xdigits}, and \code{xdisplay}. This produces a better format as shown below. <>= align(x) <- xalign(x) digits(x) <- xdigits(x) display(x) <- xdisplay(x) x @ \section{Sanitization} <>= insane <- data.frame(Name = c("Ampersand","Greater than","Less than", "Underscore","Per cent","Dollar", "Backslash","Hash","Caret","Tilde", "Left brace","Right brace"), Character = I(c("&",">","<","_","%","$", "\\","#","^","~","{","}"))) colnames(insane)[2] <- paste(insane[, 2], collapse = "") xtable(insane) @ \p Sometimes you might want to have your own sanitization function. <>= wanttex <- xtable(data.frame(label = paste("Value_is $10^{-",1:3,"}$", sep = ""))) print(wanttex, sanitize.text.function = function(str) gsub("_", "\\_", str, fixed = TRUE)) @ \subsection{Markup in tables} Markup can be included in tables, including in column and row names, by using a custom \code{sanitize.text.function}. <>= mat <- round(matrix(c(0.9, 0.89, 200, 0.045, 2.0), c(1, 5)), 4) rownames(mat) <- "$y_{t-1}$" colnames(mat) <- c("$R^2$", "$\\bar{R}^2$", "F-stat", "S.E.E", "DW") mat <- xtable(mat) print(mat, sanitize.text.function = function(x) {x}) @ % By David Dahl to demonstrate contribution from David Whitting, 2007-10-09. \p You can also have sanitize functions that are specific to column or row names. In the table below, the row name is not sanitized but column names and table elements are. <>= money <- matrix(c("$1,000","$900","$100"), ncol = 3, dimnames = list("$\\alpha$", c("Income (US$)","Expenses (US$)", "Profit (US$)"))) print(xtable(money), sanitize.rownames.function = function(x) {x}) @ \section{Format examples} \subsection{Adding a centering environment} <>= print(xtable(lm.D9, caption = "\\tt latex.environments = NULL"), floating = TRUE, latex.environments = NULL) print(xtable(lm.D9, caption = "\\tt latex.environments = \"\""), floating = TRUE, latex.environments = "") print(xtable(lm.D9, caption = "\\tt latex.environments = \"center\""), floating = TRUE, latex.environments = "center") @ \subsection{Column alignment} <>= tli.table <- xtable(tli[1:10, ]) align(tli.table) <- rep("r", 6) tli.table @ \p\textbf{\itshape Left aligned strings with column lines} <>= align(tli.table) <- "|rrl|l|lr|" tli.table @ \p\textbf{\itshape Fixed width columns} <>= align(tli.table) <- "|rr|lp{3cm}l|r|" tli.table @ \subsection{Number of digits} One number for all columns, <>= display(tli.table)[c(2,6)] <- "f" digits(tli.table) <- 3 tli.table @ \p or one for each column, including the row names, <>= digits(tli.table) <- 1:(ncol(tli)+1) tli.table @ \p or as a full matrix. <>= digits(tli.table) <- matrix(0:4, nrow = 10, ncol = ncol(tli)+1) tli.table @ \subsection{Suppress row names} <>= tli.table <- xtable(tli[1:10, ]) print(tli.table, include.rownames = FALSE) @ \p If you want a vertical line on the left, you need to change the \code{align} attribute. <>= align(tli.table) <- "|r|r|lp{3cm}l|r|" print(tli.table, include.rownames = FALSE) @ \p Revert the alignment to what is was before. <<>>= align(tli.table) <- "|rr|lp{3cm}l|r|" @ \subsection{Suppress column names} <>= print(tli.table, include.colnames = FALSE) @ \p Note the doubled header lines which can be suppressed. <>= print(tli.table, include.colnames = FALSE, hline.after = c(0,nrow(tli.table))) @ \subsection{Suppress row and column names} <>= print(tli.table, include.colnames = FALSE, include.rownames = FALSE) @ \subsection{Rotate row and column names} The \code{rotate.rownames} and \code{rotate.colnames} arguments can be used to rotate the row and/or column names. This requires \verb|\usepackage{rotating}| in the \LaTeX\ preamble. <>= print(tli.table, rotate.rownames = TRUE, rotate.colnames = TRUE) @ \subsection{Horizontal lines} \p\textbf{\itshape Line locations} Use the \code{hline.after} argument to specify the position of the horizontal lines. <>= print(xtable(anova(glm.D93)), hline.after = c(1)) @ \p\textbf{\itshape Line styles} Specifying \code{booktabs = TRUE} will generate three line types. By default, when no value is given for \code{hline.after}, a \verb|\toprule| will be drawn above the table, a \verb|\midrule| after the table headings and a \verb|\bottomrule| below the table. This requires \verb|\usepackage{booktabs}| in the \LaTeX\ preamble. \p The top and bottom rules are slightly thicker than the mid rule. The thickness of the lines can be set via the \LaTeX\ lengths \verb|\heavyrulewidth| and \verb|\lightrulewidth|. <>= tli.table <- xtable(tli[1:10, ]) print(tli.table, include.rownames = FALSE, booktabs = TRUE) @ \p If \code{hline.after} includes \code{-1}, a \verb|\toprule| will be drawn above the table. If \code{hline.after} includes the number of rows in the table, a \verb|\bottomrule| will be drawn below the table. For any other values specified in \code{hline.after}, a \verb|\midrule| will be drawn after that line of the table. \p The following table has more than one \verb|\midrule|. <>= bktbs <- xtable(matrix(1:10, ncol = 2)) hlines <- c(-1, 0, 1, nrow(bktbs)) print(bktbs, booktabs = TRUE, hline.after = hlines) @ \subsection{Table-level LaTeX} <>= print(xtable(anova(glm.D93)), size = "small") @ \subsection{Long tables} Requires \verb|\usepackage{longtable}| in the \LaTeX\ preamble. <>= x <- matrix(rnorm(1000), ncol = 10) x.big <- xtable(x, caption = 'A \\code{longtable} spanning several pages') print(x.big, hline.after=c(-1, 0), tabular.environment = 'longtable') @ %% The column name alignment is off in the following example. %% It needs some revision before exposing it. - CR, 7/2/2012 % %\p\textbf{\itshape Long tables with the header on each page} % %The \code{add.to.row} argument can be used to display the header %for a long table on each page, and to add a "continued" footer %on all pages except the last page. % %<>= %library(xtable) %x<-matrix(rnorm(1000), ncol = 10) %addtorow<-list() %addtorow$pos<-list() %addtorow$pos[[1]]<-c(0) %addtorow$command<-c(paste( % "\\hline \n", % " \\endhead \n", % " \\hline \n", % " {\\footnotesize Continued on next page} \n", % " \\endfoot \n", % " \\endlastfoot \n", sep = "")) %x.big2 <- xtable(x, label = "tabbig2", % caption = "Example of longtable with the header on each page") %print(x.big2, tabular.environment = "longtable", %include.rownames = FALSE, add.to.row = addtorow, hline.after = c(-1)) %@ \subsection{Sideways tables} Requires \verb|\usepackage{rotating}| in the LaTeX preamble. Sideways tables can't be forced in place with the \code{[H]} specifier, but you can use the \verb|\clearpage| command to get them fairly nearby. <>= x <- x[1:30, ] x.small <- xtable(x, label = 'tabsmall', caption = 'A sideways table') print(x.small, floating = TRUE, floating.environment = 'sidewaystable') @ \clearpage \subsection{Rescaled tables} Specify a \code{scalebox} value to rescale the table. <>= x <- x[1:20, ] x.rescale <- xtable(x) print(x.rescale, scalebox = 0.7) @ \subsection{Table width} The \code{tabularx} environment is for typesetting tables whose overall width is fixed. The column alignment code \code{X} denotes columns that will be stretched to achieve the desired table width. Requires \verb|\usepackage{tabularx}| in the \LaTeX\ preamble. <>= df.width <- data.frame(One = c("item 1", "A"), Two = c("item 2", "B"), Three = c("item 3", "C"), Four = c("item 4", "D")) x.width <- xtable(df.width) align(x.width) <- "|l|X|l|l|l|" print(x.width, tabular.environment = "tabularx", width = "\\textwidth") @ \section{Suppressing printing} By default the \code{print} method will print the \LaTeX\ or HTML to standard output and also return the character strings invisibly. The printing to standard output can be suppressed by specifying \code{print.results = FALSE}. <<>>= x.out <- print(tli.table, print.results = FALSE) @ Formatted output can also be captured without printing with the \code{toLatex} method. This function returns an object of class \code{"Latex"}. <<>>= x.ltx <- toLatex(tli.table) class(x.ltx) x.ltx @ \section{Acknowledgements} Most of the examples in this gallery are taken from the \code{xtable} documentation. \section{R session information} <>= toLatex(sessionInfo()) @ \end{document}