Tools for making latex tables in R [closed]
Asked Answered
S

8

268

On general request, a community wiki on producing latex tables in R. In this post I'll give an overview of the most commonly used packages and blogs with code for producing latex tables from less straight-forward objects. Please feel free to add any I missed, and/or give tips, hints and little tricks on how to produce nicely formatted latex tables with R.

Packages :

  • xtable : for standard tables of most simple objects. A nice gallery with examples can be found here.
  • memisc : tool for management of survey data, contains some tools for latex tables of (basic) regression model estimates.
  • Hmisc contains a function latex() that creates a tex file containing the object of choice. It is pretty flexible, and can also output longtable latex tables. There's a lot of info in the help file ?latex
  • miscFuncs has a neat function 'latextable' that converts matrix data with mixed alphabetic and numeric entries into a LaTeX table and prints them to the console, so they can be copied and pasted into a LaTeX document.
  • texreg package (JSS paper) converts statistical model output into LaTeX tables. Merges multiple models. Can cope with about 50 different model types, including network models and multilevel models (lme and lme4).
  • reporttools package (JSS paper) is another option for descriptive statistics on continuous, categorical and date variables.
  • tables package is perhaps the most general LaTeX table making package in R for descriptive statistics
  • stargazer package makes nice comparative statistical model summary tables

Blogs and code snippets

Related questions :

Saturnian answered 28/3, 2011 at 21:31 Comment(9)
On Cross Validated (stats.SE), the following blog post will be of interest to readers here: Some notes on making effective tables.Settling
You can also use ztable. It makes zebra-striped tables in LaTeX and HTML formats easily. It's quite flexible and simple: cran.r-project.org/web/packages/ztable/vignettes/ztable.htmlVegetative
What is the suggested "procedure" to work with many tables in R (or RStudio) and use them from an external Latex program, such as TexStudio, to embed them in a much larger project?Vegetative
@Vegetative write them in a file in R (use eg writeLines() ) and use \input{thefile} in Latex. That's how I do it if I can't just use Sweave. In all other cases Sweave in combination with xtable() works pretty well.Saturnian
@JorisMeys I use knitr instead, I guess it's similar though newer. The result can be a pdf or you can ask him to keep the intermediate generated tex files too. But there are many possibilities, headers with packages or options...Vegetative
@Vegetative For knitr the exact same goes. It's even easier, in knitr you have the kable function for this. rforge.net/doc/packages/knitr/kable.htmlSaturnian
@JorisMeys I know I should use knitr, in fact I'm already using it, but only only for single documents. What I would like to know is the proper way to create that "children" documents and embed them in bigger projects to use it from other Latex programs. For example, should I create the children with or without header specifying packages and options? What options should I change in the knitr chunks or in the xtable print function in order to get the output to embed in a larger document instead of a single one? Or should I remove that extra lines manually before assemblying?Vegetative
@Vegetative That is latex specific. If you create "children" documents, you create them as latex documents and use either include or input. You can use writeLines() which works with both kable() and xtable(). Store as .tex files and problem solved.Saturnian
OTOH, if you use multiple documents and want to combine them into one (you aren't clear on that one), you create the documents and you use input to get one document into the other ones. The latex manual will tell you that this is the same as typing the content of the document on that place, hence there's no need to copy-paste the entire setup you did in the preamble.Saturnian
N
22

I'd like to add a mention of the "brew" package. You can write a brew template file which would be LaTeX with placeholders, and then "brew" it up to create a .tex file to \include or \input into your LaTeX. Something like:

\begin{tabular}{l l}
A & <%= fit$A %> \\
B & <%= fit$B %> \\
\end{tabular}

The brew syntax can also handle loops, so you can create a table row for each row of a dataframe.

Nerine answered 28/3, 2011 at 21:31 Comment(1)
The package R.rsp and its function rstring() is similar to brew::brew(). Not sure if it is better, but the package certainly has more stuff. In either case I like this approach since it gives more flexibility in the tex code while not sacrificing reproducibility.Diffusivity
T
21

Thanks Joris for creating this question. Hopefully, it will be made into a community wiki.

The booktabs packages in latex produces nice looking tables. Here is a blog post on how to use xtable to create latex tables that use booktabs

I would also add the apsrtable package to the mix as it produces nice looking regression tables.

Another Idea: Some of these packages (esp. memisc and apsrtable) allow easy extensions of the code to produce tables for different regression objects. One such example is the lme4 memisc code shown in the question. It might make sense to start a github repository to collect such code snippets, and over time maybe even add it to the memisc package. Any takers?

Tanganyika answered 28/3, 2011 at 21:31 Comment(0)
P
18

The stargazer package is another good option. It supports objects from many commonly used functions and packages (lm, glm, svyreg, survival, pscl, AER), as well as from zelig. In addition to regression tables, it can also output summary statistics for data frames, or directly output the content of data frames.

Patch answered 28/3, 2011 at 21:31 Comment(0)
P
15

I have a few tricks and work arounds to interesting 'features' of xtable and Latex that I'll share here.

Trick #1: Removing Duplicates in Columns and Trick #2: Using Booktabs

First, load packages and define my clean function

<<label=first, include=FALSE, echo=FALSE>>= 
    library(xtable)
    library(plyr)

    cleanf <- function(x){     
        oldx <- c(FALSE, x[-1]==x[-length(x)])  
        # is the value equal to the previous?    
        res <- x
        res[oldx] <- NA
        return(res)} 

Now generate some fake data

data<-data.frame(animal=sample(c("elephant", "dog", "cat", "fish", "snake"), 100,replace=TRUE),
            colour=sample(c("red", "blue", "green", "yellow"), 100,replace=TRUE),
            size=rnorm(100,mean=500, sd=150),
            age=rlnorm(100, meanlog=3, sdlog=0.5))

    #generate a table
    datatable<-ddply(data, .(animal, colour), function(df) {
                return(data.frame(size=mean(df$size), age=mean(df$age)))
            })

Now we can generate a table, and use the clean function to remove duplicate entries in the label columns.

cleandata<-datatable
cleandata$animal<-cleanf(cleandata$animal)
cleandata$colour<-cleanf(cleandata$colour)
@ 

this is a normal xtable

<<label=normal, results=tex, echo=FALSE>>=
print(
    xtable(
        datatable
        ),
        tabular.environment='longtable',
        latex.environments=c("center"), 
        floating=FALSE, 
        include.rownames=FALSE
    )
@ 

this is a normal xtable where a custom function has turned duplicates to NA

<<label=cleandata, results=tex, echo=FALSE>>=
print(
    xtable(
        cleandata
        ),
        tabular.environment='longtable',
        latex.environments=c("center"), 
        floating=FALSE, 
        include.rownames=FALSE
    )
@ 

This table uses the booktab package (and needs a \usepackage{booktabs} in the headers)

\begin{table}[!h] 
        \centering
        \caption{table using booktabs.}
        \label{tab:mytable}
<<label=booktabs, echo=F,results=tex>>= 
            mat <- xtable(cleandata,digits=rep(2,ncol(cleandata)+1))
            foo<-0:(length(mat$animal))
            bar<-foo[!is.na(mat$animal)]
            print(mat, 
                  sanitize.text.function = function(x){x},
                  floating=FALSE,
                  include.rownames=FALSE,
                  hline.after=NULL, 
                  add.to.row=list(pos=list(-1,bar,nrow(mat)), 
                  command=c("\\toprule ", "\\midrule ", "\\bottomrule ")))
  #could extend this with \cmidrule to have a partial line over
  #a sub category column and \addlinespace to add space before a total row
@ 
Pinzler answered 28/3, 2011 at 21:31 Comment(0)
M
12

Two utilities in package taRifx can be used in concert to produce multi-row tables of nested heirarchies.

library(datasets)
library(taRifx)
library(xtable)

test.by <- bytable(ChickWeight$weight, list( ChickWeight$Chick, ChickWeight$Diet) )
colnames(test.by) <- c('Diet','Chick','Mean Weight')
print(latex.table.by(test.by), include.rownames = FALSE, include.colnames = TRUE, sanitize.text.function = force)
#   then add \usepackage{multirow} to the preamble of your LaTeX document
#   for longtable support, add ,tabular.environment='longtable' to the print command (plus add in ,floating=FALSE), then \usepackage{longtable} to the LaTeX preamble

sample table output

Morrison answered 28/3, 2011 at 21:31 Comment(1)
Is there a way to do a similar thing but with an entire data frame instead of just one vector as is input with bytable()?Oxley
F
5

Another R package for aggregating multiple regression models into LaTeX tables is texreg.

Foreyard answered 28/3, 2011 at 21:31 Comment(0)
C
5

You can also use the latextable function from the R package micsFuncs:

http://cran.r-project.org/web/packages/miscFuncs/index.html

latextable(M) where M is a matrix with mixed alphabetic and numeric entries outputs a basic LaTeX table onto screen, which can be copied and pasted into a LaTeX document. Where there are small numbers, it also replaces these with index notation (eg 1.2x10^{-3}).

Centerpiece answered 28/3, 2011 at 21:31 Comment(0)
P
5

... and Trick #3 Multiline entries in an Xtable

Generate some more data

moredata<-data.frame(Nominal=c(1:5), n=rep(5,5), 
        MeanLinBias=signif(rnorm(5, mean=0, sd=10), digits=4), 
        LinCI=paste("(",signif(rnorm(5,mean=-2, sd=5), digits=4),
                ", ", signif(rnorm(5, mean=2, sd=5), digits=4),")",sep=""),
        MeanQuadBias=signif(rnorm(5, mean=0, sd=10), digits=4), 
        QuadCI=paste("(",signif(rnorm(5,mean=-2, sd=5), digits=4),
                ", ", signif(rnorm(5, mean=2, sd=5), digits=4),")",sep=""))

names(moredata)<-c("Nominal", "n","Linear Model \nBias","Linear \nCI", "Quadratic Model \nBias", "Quadratic \nCI")

Now produce our xtable, using the sanitize function to replace column names with the correct Latex newline commands (including double backslashes so R is happy)

<<label=multilinetable, results=tex, echo=FALSE>>=
foo<-xtable(moredata)
align(foo) <- c( rep('c',3),'p{1.8in}','p{2in}','p{1.8in}','p{2in}' )
print(foo, 
            floating=FALSE, 
            include.rownames=FALSE,
            sanitize.text.function = function(str) {
                str<-gsub("\n","\\\\", str, fixed=TRUE)

                return(str)
            }, 
            sanitize.colnames.function = function(str) {
                str<-c("Nominal", "n","\\centering Linear Model\\\\ \\% Bias","\\centering Linear \\\\ 95\\%CI", "\\centering Quadratic Model\\\\ \\%Bias", "\\centering Quadratic \\\\ 95\\%CI \\tabularnewline")
                return(str)
            })
@  

(although this isn't perfect, as we need \tabularnewline so the table is formatted correctly, and Xtable still puts in a final \, so we end up with a blank line below the table header.)

Pinzler answered 28/3, 2011 at 21:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.