As a statistician, I collaborate with a lot of clinicians, and therefore need to be producing reports in word. Let’s not go any further into it, but I need to create beautiful Rmarkdown reports that knit to word. This feels wierd to write a html Rmarkdown about writing Rmarkdown reports in word, but lets get started!
Example data
First lets get an example clinical trial dataset that we might want to summarise, and some packages that we will need.
library(knitr)
library(survival) #pbc dataset lives here
data(pbc)
suppressPackageStartupMessages(library(tidyverse))
suppressPackageStartupMessages(library(janitor))
suppressPackageStartupMessages(library(knitr)) # to kable
suppressPackageStartupMessages(library(flextable)) #to flextable
Summary table
OK. So lets start with creating our summary table. If you havent used the tabyl
function in janitor
, get on it!
#glimpse(pbc)
pbc %>%
tabyl(stage, trt) %>%
adorn_totals() %>%
adorn_percentages("col") %>%
adorn_pct_formatting(digits = 1) %>%
adorn_ns("front") ->t1
Tables in word
Now, typically if you want to print this nicely in Rmarkdown, you would use kable
(or maybe kableextra
). That would look like this:
t1 %>%
select(stage, `1`, `2`) %>%
kable(col.names = c("Stage", "Placebo", "Treatment"))
Stage | Placebo | Treatment |
---|---|---|
1 | 12 (7.6%) | 4 (2.6%) |
2 | 35 (22.2%) | 32 (20.8%) |
3 | 56 (35.4%) | 64 (41.6%) |
4 | 55 (34.8%) | 54 (35.1%) |
NA | 0 (0.0%) | 0 (0.0%) |
Total | 158 (100.0%) | 154 (100.0%) |
So while there are plenty of ways to beautify this in html or latex (pdf), there aren’t a lot of options for anyone to render in word.
Enter, flextable
. Thankyou David Gohel! His also the author of officer
, another amazing package for writing Rmarkdown reports in word.
So how do we use flextable
?
t1 %>%
select(stage, `1`, `2`) %>%
filter(is.na(stage)==FALSE) %>%
flextable() %>%
set_header_labels() %>%
knit_print()
stage | 1 | 2 |
1 | 12 (7.6%) | 4 (2.6%) |
2 | 35 (22.2%) | 32 (20.8%) |
3 | 56 (35.4%) | 64 (41.6%) |
4 | 55 (34.8%) | 54 (35.1%) |
Total | 158 (100.0%) | 154 (100.0%) |
Its that easy. But now lets beautify with all of the functions that you might want to use, and the ones that will work in rendering to word.
t1 %>%
select(stage, `1`, `2`) %>%
filter(is.na(stage)==FALSE) %>%
add_row(stage="Stage", .before = 1) %>%
flextable() %>%
set_caption("Stage of disease by treatment") %>%
set_header_labels(stage=" ",`1`="Placebo", `2`="Treatment" ) %>%
align(j=1, align = "left", part = "all") %>%
align(j=2:3, align = "center", part = "all") %>%
bold( i=c(1)) %>%
font(fontname = "Calibri", part="all") %>%
padding(i=c(2:5), j=1, padding.left = 20) %>%
set_table_properties(width = 1, layout = "autofit") %>%
knit_print()
| Placebo | Treatment |
Stage | ||
1 | 12 (7.6%) | 4 (2.6%) |
2 | 35 (22.2%) | 32 (20.8%) |
3 | 56 (35.4%) | 64 (41.6%) |
4 | 55 (34.8%) | 54 (35.1%) |
Total | 158 (100.0%) | 154 (100.0%) |
Now, this has rendered a bit wierdly in my blog, due to the Blog formatting etc. Please trust me this is lovely in word.
Lets unpack some of these functions.
set_caption
is the table caption in word.set_header_labels
are the column namesalign
aligns the columns, andpart="all"
means we want to align the header as well as the table data.j
specifies the columns that you wish to align.bold
is used to make a row bold (row 1 asi=1
). You can also useitalics
font
sets the font of the table datapadding
- my absolute favourite - adds some space to indent the column/row specified. You can also pad right if you want to (or top or bottom)set_table_properties
fits the table to the width of the word document. Its not great when I render it here in html but trust me, its great in word.
Some further notes when you are setting up the Rmarkdown file.
Table numbering
In order to create the autonumbering for the table numbers in word, use the following code in your setup chunk:
library(officer)
library(flextable)
autonum <- run_autonum() #to number the tables
It only needs to be done once in that setup chunk. Then in your flextables, make sure you add in the following option autonum=autonum
like so:
t1 %>%
flextable() %>%
set_caption("Table 1", style = "Table Caption", autonum = autonum)
Header rows
They just magically are setup properly and for big tables that flow onto a second page, the header names follow onto the second page!
You can also add_header_row
that might merge columns together! In word!!
Share this post
Twitter
Google+
Facebook
Reddit
LinkedIn
StumbleUpon
Pinterest
Email