Make automatic reports

Dan Chaltiel

2021-03-05

Create reports with officer

The real power of crosstable comes out when used with David Gohel’s awesome package officer, which allows to automatically create MS Word documents.

Therefore, crosstable has several helper functions to output a beautiful report:

library(officer)
library(ggplot2)
ct1=crosstable(iris, by=Species, test=TRUE)
ct2=crosstable(mtcars2, c(mpg,cyl,disp), by=am, effect=TRUE, total="both", showNA="always")
ct3=crosstable(esoph)
options(crosstable_units="cm")

my_plot = ggplot(data = iris ) +
  geom_point(mapping = aes(Sepal.Length, Petal.Length))

doc = read_docx() %>% 
  body_add_title("Dataset iris", 1) %>%
  body_add_title("Not compacted", 2) %>%
  body_add_normal("Table \\@ref(table_autotest) is an example. However, automatic testing is bad and I should feel bad.") %>%
  body_add_crosstable(ct1) %>%
  body_add_table_legend("Automatic testing is bad", bookmark="table_autotest") %>%
  body_add_normal("Let's add a figure as well. You can see in Figure \\@ref(fig_iris) that sepal length is somehow correlated with petal length.") %>%
  body_add_figure_legend("Relation between Petal length and Sepal length", bookmark="fig_iris") %>% 
  body_add_gg2(my_plot, w=14, h=10, scale=1.5) %>% 
  body_add_title("Compacted", 2) %>%
  body_add_normal("When compacting, you might want to remove the test names.") %>%
  body_add_crosstable(ct1, compact=TRUE, show_test_name=FALSE) %>%
  body_add_break() %>%
  body_add_title("Dataset mtcars2", 1) %>%
  body_add_normal("This dataset has {nrow(ct3)} rows and {x} columns.", x=ncol(ct3)) %>%
  body_add_normal("Look, there are labels!") %>%
  body_add_crosstable(ct2, compact=TRUE) %>%
  body_add_break() %>%
  body_add_title("Dataset esoph", 1) %>%
  body_add_normal("This one was compacted beforehand for some reason.") %>%
  body_add_crosstable(compact(ct3))

Beware when using the whole tidyverse, as crosstable::compact conflicts with purrr::compact. You can solve this using an alias (my_compact=crosstable::compact) or using the conflicted package.

Output

To save the file, just use the print function:

filename=file.path("..", "examples", "vignette_officer.docx", fsep="\\")#`\\` is needed for shell.exec on Windows
print(doc, filename) #write the docx file
shell.exec(filename) #open the docx file (fails if it is already open)

You can check out this example here.

Unfortunately, large tables can overflow the MS Word document width. In this case (for instance for mtcars2 in the previous example), you have to manually go to Table Tools > Layout > AutoFit > AutoFit Window in the ribbon to correct the width.

You can learn more on officer on its documentation.

Create reports with Rmarkdown

Knitting (knitr::knit() or via RStudio) this Rmd code also creates a MS-Word file. Here, you can use the power of bookdown to generate the automatic numbering of the tables.


---
title: "Iris"
output: bookdown::word_document2
---
    
```{r setup, include=FALSE}
library(crosstable)
library(flextable)
library(dplyr) #pour le pipe %>% 
```

Table iris is given in Table \@ref(tab:irisTable).

```{r description, echo=FALSE, results='asis'}
cat("<caption> (\\#tab:irisTable) Table Iris </caption> \n\r ")
crosstable(iris, Sepal.Length, Sepal.Width, by=Species, test = TRUE, total="column") %>% as_flextable
```

You can example files here: vignette_markdown.Rmd and vignette_markdown.docx.