Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

The package flextable is existing since mid 2016 and I did not made any communication about it; obviously if I wrote it, I’d like it to be used by R users! That post is an attempt to fix that.

The flextable package makes it simpler to create tables for reporting purposes. The goal of the package is to provide a set of functions that can be used to design and format tabular reporting.

It’s been originally written in order to provide an alternative to ReporteRs::FlexTable objects that are not supported by package officer.

## What the flextable package does

It lets customize tables, their formats and their contents. Formatting can be done on cells, paragraphs and text. It also lets you to insert headers and footer rows with eventually merged cells.

Common operations can be made with simple functions, i.e. use bold() to make a table selection bold, use align() to set alignment, merge_at() to merge contiguous cells, etc. Conditional formatting is possible with each of these functions.

## Supported outputs

These objects can be rendered with R markdown documents. There is a knitr::knit_print method for HTML output and for Word output (thanks to Maxim Nazarov). Note that you will need pandoc >= 2.0.0 if you want to use Word output.

These objects can also be used with package officer and can be rendered into Word and PowerPoint documents (and Excel when I will find time and motivation for it).

## xtable

A work started to support outputs from package xtable. It make statistical reporting easier for those used to work with xtable.

For now, only xtable objects are supported but xtableList will also be supported later.

library(xtable)
library(flextable)
temp.ts <- ts(cumsum(1 + round(rnorm(100), 0)),
start = c(1954, 7), frequency = 12)
ft <- xtable_to_flextable(x = xtable(temp.ts, digits = 0),
NA.string = "-")
ft
 Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec 1954 1.000 2.000 2.000 4.000 6.000 8.000 1955 9.000 12.000 13.000 14.000 14.000 13.000 16.000 16.000 17.000 17.000 18.000 17.000 1956 19.000 21.000 22.000 22.000 22.000 22.000 25.000 26.000 27.000 27.000 29.000 32.000 1957 32.000 33.000 33.000 34.000 35.000 35.000 37.000 36.000 38.000 39.000 39.000 40.000 1958 39.000 40.000 41.000 43.000 44.000 45.000 46.000 47.000 48.000 49.000 49.000 51.000 1959 52.000 53.000 54.000 55.000 56.000 57.000 56.000 55.000 55.000 57.000 56.000 56.000 1960 56.000 58.000 60.000 61.000 63.000 64.000 67.000 69.000 70.000 71.000 73.000 76.000 1961 77.000 75.000 77.000 77.000 77.000 79.000 79.000 81.000 81.000 82.000 83.000 84.000 1962 85.000 86.000 87.000 88.000 88.000 88.000 89.000 91.000 92.000 93.000

## Preview

the function print() makes it easier to view the flextable inside all supported format.

By default, the print method display the flextable in an HTML page, if you are running R with RStudio, the flextable is displayed in the Viewer as an HTML table.

This can be change with argument preview. The document will be opened with the application associated to the file extension (Word or PowerPoint). This will not work on a Web server, i.e. RStudio Server.

library(flextable)

ft <- theme_vanilla(ft)
ft <- width(ft, width = 1)
ft
 Sepal.Length Sepal.Width Petal.Length Petal.Width Species 5.1 3.5 1.4 0.2 setosa 4.9 3.0 1.4 0.2 setosa 4.7 3.2 1.3 0.2 setosa 4.6 3.1 1.5 0.2 setosa 5.0 3.6 1.4 0.2 setosa 5.4 3.9 1.7 0.4 setosa
print(ft, preview = "log")
#> a flextable object.
#> col_keys: Sepal.Length, Sepal.Width, Petal.Length, Petal.Width, Species
#> body has 6 row(s)
#> original dataset sample:
#>   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> 1          5.1         3.5          1.4         0.2  setosa
#> 2          4.9         3.0          1.4         0.2  setosa
#> 3          4.7         3.2          1.3         0.2  setosa
#> 4          4.6         3.1          1.5         0.2  setosa
#> 5          5.0         3.6          1.4         0.2  setosa
print(ft, preview = "docx")
print(ft, preview = "pptx")

## Detailed example

Let’s first create a data.frame example from a sample of mtcars. We will use it as data source for our reporting table.

library(tibble)
library(magrittr)

dataset <- mtcars %>%
rownames_to_column(var = "car_name") %>%
print()
#>            car_name  mpg cyl disp  hp drat    wt  qsec vs am gear carb
#> 1         Mazda RX4 21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
#> 2     Mazda RX4 Wag 21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
#> 3        Datsun 710 22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
#> 4    Hornet 4 Drive 21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
#> 5 Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
#> 6           Valiant 18.1   6  225 105 2.76 3.460 20.22  1  0    3    1

Now let’s use flextable API:

myft <- regulartable( dataset,
col_keys = c("car_name", "am", "carb", "gear", "blank", "mpg", "drat" )) %>%
theme_vanilla() %>%
width(j = c("am", "carb", "gear", "mpg", "drat" ), width = 1) %>%
width(j = 1, width = 2)
myft
 car_name am carb gear mpg drat Mazda RX4 1 4 4 21.0 3.90 Mazda RX4 Wag 1 4 4 21.0 3.90 Datsun 710 1 1 4 22.8 3.85 Hornet 4 Drive 0 1 3 21.4 3.08 Hornet Sportabout 0 2 3 18.7 3.15 Valiant 0 1 3 18.1 2.76

We’ve just created a simple table. Let’s customize printed values.

# Change labels
myft <- myft %>%
car_name = "Car name", am = "Transmission", carb = "# carburetors",
gear = "# forward gears", mpg = "Miles/(US) gallon", drat = "Rear axle ratio")
myft <- myft %>%
merge_at(i = 1, j = c("mpg", "drat"), part = "header") %>%
set_formatter(
am = function(x) ifelse( x < 1, "automatic", "manual"),
carb = function(x) sprintf("%.0f", x),
gear = function(x) sprintf("%.0f", x)
)
myft
 Some measures Car name Transmission # carburetors # forward gears Miles/(US) gallon Rear axle ratio Mazda RX4 manual 4 4 21.0 3.90 Mazda RX4 Wag manual 4 4 21.0 3.90 Datsun 710 manual 1 4 22.8 3.85 Hornet 4 Drive automatic 1 3 21.4 3.08 Hornet Sportabout automatic 2 3 18.7 3.15 Valiant automatic 1 3 18.1 2.76

And now let’s add some formattings.

myft <- myft %>%
bold(i = 3, bold = TRUE) %>% bold(j = 3, bold = TRUE) %>%
color(j = 3, color = "#4790b5") %>% color(i = 3, color = "#d24625") %>%
align(j = 3:6, align = "center", part = "all") %>%
empty_blanks()
myft
 Some measures Car name Transmission # carburetors # forward gears Miles/(US) gallon Rear axle ratio Mazda RX4 manual 4 4 21.0 3.90 Mazda RX4 Wag manual 4 4 21.0 3.90 Datsun 710 manual 1 4 22.8 3.85 Hornet 4 Drive automatic 1 3 21.4 3.08 Hornet Sportabout automatic 2 3 18.7 3.15 Valiant automatic 1 3 18.1 2.76

myft <- autofit(myft)
myft
 Some measures Car name Transmission # carburetors # forward gears Miles/(US) gallon Rear axle ratio Mazda RX4 manual 4 4 21.0 3.90 Mazda RX4 Wag manual 4 4 21.0 3.90 Datsun 710 manual 1 4 22.8 3.85 Hornet 4 Drive automatic 1 3 21.4 3.08 Hornet Sportabout automatic 2 3 18.7 3.15 Valiant automatic 1 3 18.1 2.76

## With package officer

The following code is producing a PowerPoint document containing the flextable.

library(officer)
add_slide(layout = "Title and Content", master = "Office Theme") %>%
ph_with_flextable(myft, type = "body") %>%
print(target = "../../static/files/flextable_example_01.pptx")

The following code is producing a Word document containing the flextable.

library(officer)
print(target = "../../static/files/flextable_example_01.docx")