Introduction

flextable is a fantastic package for tabulating static tables. The outputs can be saved as (html, docx, ptx, png) formats and its grammar is similar to that of ggplot2, where each additional aspect to a table is build-up of statements separate by the pipe symbol “%>%”. The API is very well designed with rich functionalities. You can set different themes, re-attribute borders and change font sizes etc; not only that, you can even hone in and conditionally format contents at cell level; merge cells vertically and horizontally. Another nice feature is the inclusion of mini-plots and images to give more insight of the data and makes a table more attractive. flextable comes with four mini-plot types; box, density, points and line but it also offers a general gg_chunk function to include any ggplot2 object you care to create. The purpose of this post is to introduce flextable and share some examples.

Table Anatomy and Concepts

You will observe a table is composed of 3 parts; header, body and footer and may envisage the general concepts of tabulating as shown in Fig i. There is a wealth of documentations by the author(s) already, so I will refer you to the references in the appendix for details. However I am particularly drawn to the three features presented in the examples below.

Fig i


Examples

There are many aspects and features that I like about flextable, such as its API, conditional formatting, theming and how it works in companion with other packages but the below are the ‘most’ appealing to me for now.

Example 1
This example shows the inclusion of png files (images) via the colformat_image function. Such images make the table much more attractive and will draw attention. Note the “Flag” variable stores the full paths of the png files and is being referred to by the colformat_image function.

library(flextable)
library(magrittr)

df <- data.frame( Country    = c("USA", "Japan", "Germany", "UK", "France", "Italy", "Canada"),     
                  Flag       = c("us.png", "jp.png", "de.png", "gb.png", "fr.png", "it.png", "ca.png"),
                  Population = c(331002651, 126476461, 83783942, 67886011, 65273511, 60461826, 37742154),
                  YearlyChg  = c(" 0.59 %", "-0.30 %", " 0.32 %", " 0.53 %", " 0.22 %", "-0.15 %", " 0.89 %"),
                  NetChg     = c(1937734, -383840, 266897, 355839, 143783, -88249, 331107),
                  Density    = c(36, 347, 240, 281, 119, 206, 4),            
                  LandArea   = c(9147420, 364555, 348560, 241930, 547557, 294140, 9093510),
                  Migrant    = c(954806, 71560, 543822, 260650, 36527, 148943, 242032),
                  FertRate   = c(1.8, 1.4, 1.6, 1.8, 1.9, 1.3, 1.5),
                  MedAge     = c(38, 48, 46, 40, 42, 47, 41),
                  WorldShare = c("4.25 %", "1.62 %", "1.07 %", "0.87 %", "0.84 %", "0.78 %", "0.48 %")
                          )

ft <- flextable(df) %>%
  colformat_image(j = "Flag", width = 0.5, height = 0.33) %>%
  ...


Fig 1



Example 2
Presenting summary data along with its distributions plots will give more insight to the data. flextable includes three such mini-plots; Box, Density and Line as show in this example where they are wrapped inside the compose functions.

...

ft <- flextable(
  data = hgb,
  col_keys = c("visit", "n", "mean", "min", "max", "box", "density", "line")
  ) %>%

set_caption(caption = "Haemoglobin (g/dL)") %>%
  
set_header_labels(visit = "Visit", n = "n", mean = "Mean", min = "min", max = "max", box = "Box Plot", density = "Density Plot", line = "Line Plot") %>%
  
compose(j = "box", value = as_paragraph(
  plot_chunk(
    value = aval, type = "box",
    width = 1.5, height = .4
  )
)) %>%
    
compose(j = "density", value = as_paragraph(
  plot_chunk(value = aval, type = "dens", 
             width = 1.5, height = .4)
)) %>%
  
  
compose(j = "line", value = as_paragraph(
  plot_chunk(value = aval, type = "line", 
               width = 1.5, height = .4)
)) 

...


Fig 2



Example 3
From example 2 you will wonder - is it possible to have other types of mini-plots in the table? Yes! It just needs to be a ggplot2 object to be included via the gg_chunk function. Note you can usually covert other plot’s object to a ggplot2 object and therefore you do not have the restriction of just ggplot2 plots! Also there is no reason why you can’t save ggplot2 plots as png and include them as in example 1.

...
#  the key to this example is the **gg_chunk** function and its usage is as shown below. Note the value parameter holds the gg object stored in a list column. Refer to the vignette for details.

ft <- mk_par(ft, j = "gg",
             value = as_paragraph(
             gg_chunk(value = gg, width = 2, height = 1)
             ))

...


Fig 3


Further Research

Some companion packages to flextable are officer, ftExtra and gtsummary so you may wish to explore these also.

Conclusion

flextable is very well designed and has many features and functionalities to produce publication ready tables.


Contact

Email: