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 butxtableList
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 <- regulartable(head(iris)) 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` #> header has 1 row(s) #> 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") %>% head() %T>% 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 %>% set_header_labels( car_name = "Car name", am = "Transmission", carb = "# carburetors", gear = "# forward gears", mpg = "Miles/(US) gallon", drat = "Rear axle ratio") myft <- myft %>% add_header(mpg = "Some measures") %>% 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 |
Finally, adjust widths and heights:
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) read_pptx() %>% add_slide(layout = "Title and Content", master = "Office Theme") %>% ph_with_flextable(myft, type = "body") %>% print(target = "../../static/files/flextable_example_01.pptx")
Download file flextable_example_01.pptx – view with office web viewer
The following code is producing a Word document containing the flextable.
library(officer) read_docx() %>% body_add_flextable(value = myft) %>% print(target = "../../static/files/flextable_example_01.docx")
Download file flextable_example_01.docx – view with office web viewer
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.