# Word Up - automatic reporting with MS Word, Officedown and flextable

Recreating existing Word reports in RMarkdown with Officer, Officedown and flextable.

Background: I’m currently working on a project where I am using parameterised rmarkdown for the first time - hooray! This will end up as 13 separate documents of about 30 pages, with lots of tables and charts. This is the first phase of many similar documents.

But, I have to render my final output to Word, which, I’m not going to lie, was a bit of a worry.
That’s a lot of Word, and a lot of scope for things to go wrong.

While I’m not adverse to Excel, I am far from a fan of Word.
Much of this is because of its infuriating layout quirks when it comes to margins,figures and tables.

The {officer}, {officedown} and {flextable} packages make working with Word easier.
You can use {officer} to create Word and Powerpoint documents when working in R, {officedown} to do the same in R Markdown, and {flextable} for, well, tables.

The advantage of {officedown} is it allows dynamic figure and table captions, cross referencing, and whole host of other features ( like multi column layouts, changing page orientation, and different formats for different sections) {officer} is a lower level package, where you work with adding paragraphs, and other blocks. One of my favourite features is block_pour_docx which allows you to insert an entire page, or even an entire document, into your rmarkdown file, as a one-liner.

{flextable} is not just for Word, and ranks alongside {gt} as a general purpose solution for all your table needs. If you haven’t considered it before now, it is definitely worth spending some time on.

There’s not a lot of blog posts out there for working with these packages, especially for Word.
Or, at least, not in comparison to working with PowerPoint or Rmarkdown generally.

Alison Hill wrote a post detailing her friction log when working with Powerpoint, so consider this my friction log of working with Word.

(These are in no particular order)

## Applying your departmental / organisational styles

You will see advice that says you need to knit a regular Word document ( from the New File menu item in RStudio), then open it (it doesn’t need any content) and then amend the styles in this document, before passing it to officer as a reference document.

My colleagues already had a .dot template with our departmental styles applied. I found that I could use that (after I’d saved a copy as a .docx file) and the styles were picked up by {officedown}. No need to generate a blank file and amend everything from scratch (there are a lot of style elements and it would have been really tedious). If you already have a document with styles in place, you should be good to go. Here’s how my Rmd file looked. You specify rdocx_document as the output format, and I saved my template file in the root directory so it was easy to reference :

output:
officedown::rdocx_document:
reference_docx: "my_report_template.docx"

## Adding a row to a table to create space / improve presentation

Throughout this project I’m recreating an existing suite of tables and plots that have, until now, been produced in Excel & Word. The first table had totals at Scotland, Council and Health Board level, then a space, then a range of lower level data.

Once I’d got the data into shape, I first added the space using dplyr::add_row().

But, over time, this felt wrong - I didn’t like the idea of adding an unnecessary empty row to a dataframe, especially if I might need it for further analysis later on.

flextable::flextable(df) %>%

Here I’m adding padding to rows 1 and 9 of my table ( flextable uses the i and j conventions for applying functions and modifications to rows and columns), and ensuring the padding goes at the bottom by setting padding.top to FALSE.

## Setting row heights

Another way to improve presentation in some of my tables was to reduce row heights for some rows, and increase it for others.

out_table  %>%
flextable::height(., i = c(4), height = .015, part = "body") %>%
flextable::height(., i = c(1, 2, 3, 5, 6, 7, 8, 9, 10, 12, 13), height = .25,
part = "body")

Row 4 gets less space, while the other row heights are increased. N.B - I thought I could do something like

flextable::height(., i = c(1:3, 5:10, 12:13), height = .25,
part = "body")

but it didn’t seem to like it, so each row got entered individually instead.

## Amending number formats for specific columns

Here I amend the 3rd, 4th and 5th columns - because the 3rd column name is dynamic, I didn’t want to refer to it by name

flextable::flextable(table_data, cwidth = 1.05) %>%
flextable::colformat_double(.,j = c(3, 4, 5), digits = 1) %>%

For other tables, where I know the column names are static, I can enter the names directly:

flextable::flextable(table_data, cwidth = 1.05) %>%
flextable::colformat_double(.,j = c("Rate","Lower bound","Upper bound"), digits = 1)

I needed to add header row above the final two columns in my seven column table, denoting whether there was a statistically significant difference between them and a reference value.

The first 5 columns get passed nothing, while “Significance” spans the final two columns.

## Highlighting a row

Using bg, we can add a custom background colour to highlight a specific row.

I found that when creating the table in a function, I had to to use the which syntax below:

flextable::bg(out_table,

## Inserting cover images

I’m going to leave that for the next post, which I hope will be published within the next few days..so please look out for the follow up post!