---
title: "Using table1 with \\LaTeX{} and MS Word"
author: "Benjamin Rich"
date: "`r Sys.Date()`"
output:
  pdf_document:
    #latex_engine: xelatex
    #latex_engine: lualatex
    #keep_tex: true
tables: true
header-includes:
  - \usepackage{booktabs}
  - \usepackage{longtable}
  - \usepackage{array}
  - \usepackage{multirow}
  - \usepackage{wrapfig}
  - \usepackage{float}
  - \usepackage{colortbl}
  - \usepackage{pdflscape}
  - \usepackage{tabu}
  - \usepackage{threeparttable}
  - \usepackage{threeparttablex}
  - \usepackage[normalem]{ulem}
  - \usepackage{makecell}
  - \usepackage{xcolor}
vignette: >
  %\VignetteIndexEntry{Using table1 with \LaTex{}}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteDepends{kableExtra,flextable,printr}
  %\VignetteEncoding{UTF-8}
---

```{r echo=FALSE, message=FALSE, warning=FALSE, results='hide'}
library(kableExtra, quietly=TRUE)
library(flextable, quietly=TRUE)
library(table1, quietly=TRUE)
try(detach('package:printr', unload = TRUE), silent=TRUE) # Make sure printr is not loaded

f <- function(x, n, ...) factor(sample(x, n, replace=TRUE, ...), levels=x)
set.seed(427)

n <- 146
dat <- data.frame(id=1:n)
dat$treat <- f(c("Placebo", "Treated"), n, prob=c(1, 2)) # 2:1 randomization
dat$age   <- sample(18:65, n, replace=TRUE)
dat$sex   <- f(c("Female", "Male"), n, prob=c(.6, .4))  # 60% female
dat$wt    <- round(exp(rnorm(n, log(70), 0.23)), 1)

# Add some missing data
dat$wt[sample.int(n, 5)] <- NA

label(dat$age)   <- "Age"
label(dat$sex)   <- "Sex"
label(dat$wt)    <- "Weight"
label(dat$treat) <- "Treatment Group"

units(dat$age)   <- "years"
units(dat$wt)    <- "kg"
```


## Introduction

A long requested feature has been the ability to use `table1` in `rmarkdown`
documents that render to \LaTeX{} or `.docx` (i.e.
Microsoft\textsuperscript{\textregistered} Word).  Since version 1.4 of
`table1`, this is now possible (with some limitations) by converting the output
of `table1()` to a `data.frame`, `kableExtra` or `flextable`, using the
functions `as.data.frame()`, `t1kable()` and `t1flex()` respectively, as these
objects can be rendered to \LaTeX{} (note: `data.frame` (via pandoc) and
`flextable` objects can also be rendered to .docx format, while, `kableExtra`
cannot).

## Examples

We demonstrate this using a familiar example from the main vignette. First, we
can try the `data.frame` approach:

```{r}
x <- table1(~ age + sex + wt | treat, data=dat)
as.data.frame(x)
```

By default, this does not produce a \LaTeX{} table, but the same text output you
would see in the R console. If the `printr` package is loaded, however, we do
get a \LaTeX{} table by default:

```{r}
library(printr, quietly=TRUE)
as.data.frame(x)
```

Alternatively, we can use the `knitr::kable()` function:

```{r}
kable(as.data.frame(x), booktabs=TRUE)
```

The output here is a bit nicer because we have specified the `booktabs` option,
but because we are talking about a simple `data.frame`, there is no option to
specify formatting (like bold text for variable labels, for instance).

Next, we can try the `t1kable()` function, to produce a `kableExtra` object:

```{r}
t1kable(x)
```

This looks a bit better: it uses the `booktabs` option by default, and also
has bold variable labels. But because of a limitation with multiline headers
(i.e. headers that contain line breaks), the `N=XX` for each column is placed
in the first row of the table, which is less than ideal.

Finally, we can try using the `t1flex()` function to produce a  `flextable` object:

```{r}
t1flex(x)
```

(Note that that `flextable` output, in particular the font, is different
depending on whether the `xelatex`, `lualatex` or `pdflatex` engine is used,
and `flextable` emits a warning when `pdflatex`, the default for `rmarkdown`
documents,  is used because `xelatex` and `lualatex` gives more font options.)

The output is less attractive in my opinion, and less consistent with the
typical look of \LaTeX{} tables and documents. It is more spaced out, doesn't
have bold labels or line break in the column headers (actually, this is a
problem common to both packages, but the `t1kable()` and `t1flex()` functions
deal with it differently because `flextable` will actually include the line
breaks in HTML and .docx output, and the overall best approach is unclear), and
doesn't use the `booktabs` package (the thickness of the horizontal rules is
different).  Also, `flextable` places the table in a float, whereas
`kableExtra` leaves it inline.  I personally would use `kableExtra` over
`flextable` in a \LaTeX{} documents, and in fact I have made this the default
output in a \LaTeX{} context (i.e., when using `rmarkdown` with a \LaTeX{} output
format).  But a big advantage of `flextable` is that in can render to .docx
format (i.e.  Microsoft Word), which `kableExtra` cannot, and is the default
output in that context.


### Nested groups

Nested groups are supported with `kableExtra` and `flextable`, but not simple
`data.frame`s. Here, one example with `kableExtra`:

```{r}
x2 <- table1(~ age + wt | treat*sex, data=dat, overall=FALSE)
t1kable(x2)
```

### Captions and footnotes

Captions and footnotes are supported with both `kableExtra` and `flextable`. An
example with `kableExtra`:

```{r}
x <- table1(~ age + sex + wt | treat, data=dat,
    caption="Test caption", footnote="Test footnote")
t1kable(x)
```

Alternatively, the `kableExtra::footnote()` function can be used to add
footnotes to the resulting object (this function also does automatic numbering,
which may be considered an advantage). Note that when a caption is used, the
table is rendered as a float.

## Closing remarks

As of version 1.4, it is now possible to use `table1` within \LaTeX{} documents.
There are some limitations on the formatting, however (it looks fine, but not
quite the same as the HTML output and there is less flexibility to control it).

The actual \LaTeX{} code generation is handled by an external package (i.e.,
`knitr`, `kableExtra` or `flextable`).  The \LaTeX{} generated by `kableExtra` and
`flextable` is very different, and in my opinion `kableExtra` produces the
better result.  Both `kableExtra` and `flextable` have an extensive number of
functions that can be applied to the converted object in order to alter the
appearance of the table but these will not be described here; refer to each
package's documentation for the complete details.

