flextable 0.4.0 is out

David Gohel

2018/01/11

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.

regulartable bold set_header_labels border display merge_h rotate padding style align italic add_header body_add_flextable fontsize bg ph_with_flextable color autofit merge_at width void merge_v flextable knit_print.flextable set_header_df

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

3.000

6.000

8.000

10.000

12.000

1955

13.000

14.000

15.000

16.000

20.000

22.000

21.000

21.000

21.000

22.000

22.000

24.000

1956

26.000

28.000

29.000

30.000

31.000

33.000

32.000

32.000

34.000

36.000

36.000

36.000

1957

37.000

39.000

41.000

42.000

42.000

43.000

43.000

44.000

45.000

48.000

49.000

49.000

1958

51.000

53.000

54.000

55.000

56.000

58.000

59.000

59.000

59.000

59.000

60.000

63.000

1959

63.000

65.000

66.000

68.000

69.000

69.000

69.000

70.000

72.000

73.000

73.000

73.000

1960

73.000

75.000

76.000

75.000

76.000

77.000

77.000

79.000

82.000

84.000

85.000

86.000

1961

87.000

87.000

88.000

89.000

90.000

92.000

94.000

96.000

97.000

98.000

100.000

101.000

1962

102.000

102.000

103.000

104.000

105.000

106.000

107.000

109.000

110.000

110.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(myft, ph_location_type(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