Format flextable objects

Default formatting properties

When a flextable is created (when function flextable is called), some default values are used as formatting properties, the font family, the font size, padding, text alignment… They can be read with function get_flextable_defaults().

as.data.frame(get_flextable_defaults())
#>   font.family font.size font.color text.align padding.bottom padding.top
#> 1   Helvetica        14      black       left              3           3
#>   padding.left padding.right border.color background.color table.layout
#> 1            3             3        black      transparent        fixed
#>   decimal.mark big.mark digits na_str fmt_date      fmt_datetime fonts_ignore
#> 1            .        ,      2        %Y-%m-%d %Y-%m-%d %H:%M:%S        FALSE
#>        theme_fun
#> 1 theme_booktabs

These default properties will be used when creating the flextable and sometimes by the theme functions.

They can be updated with function set_flextable_defaults().

It makes possible to set some global options that apply to all tables in e.g. an Rmd file where they should be set in the first chunk. In short, call this feature at the beginning of your Markdown script or documentR Markdown to get flextables that share the same font, font size, color, alignment, and so on.

set_flextable_defaults(
  font.family = "Helvetica", font.size = 12, font.color = "black",
  text.align = "left", 
  table.layout = "fixed",
  theme_fun = "theme_booktabs")

Note that it is also possible to set the default theme that will be the last instruction called when creating the flextable. If you don’t want to apply a theme, fill in the default theme with this function: theme_fun = function(x) x.

Using part

A flextable is made of parts, an header, a body and a footer. To specify which part formatting instructions should affect, use argument part. Possible values are:

Shortcuts functions

There are simple functions to modify formatting properties of flextable objects: bg, bold, border, color, padding, fontsize, italic, align, …

They are illustrated in the examples below.

myft <- flextable(head(iris))
myft

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

bold

myft <- flextable(head(iris)) 
myft <- bold(myft, part = "header") # bold header
myft

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

Font size

myft <- fontsize(myft, part = "header", size = 12) 
myft

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

change font color

myft <- color(myft, color = "#E4C994")
myft

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

color can be a vector and also a function that returns a character vector of colors (see scales::col_numeric).

Italic

myft <- italic(myft, i = ~ Sepal.Length > 5, 
         j = ~ Sepal.Length + Sepal.Width, italic = TRUE)
myft

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

change background color

# light gray as background color for header
myft <-  bg(myft, bg = "#E4C994", part = "header")
# dark gray as background color for body
myft <-  bg(myft, bg = "#333333", part = "body")
myft

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

Text alignment

myft <- align( myft, align = "center", part = "all" )
myft

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

add padding

myft <- padding( myft, padding = 6, part = "all" )
myft

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

change font

myft <- font(myft, j = "Species", fontname = "Times")
myft <- fontsize(myft, j = "Species", size = 14)
myft

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

highlight text

Text can be highlighted with function highlight. Color can be a single value, multiples values or a function (from {scales} for example).

ft <- flextable(head( mtcars, n = 10))
ft <- highlight(ft, j = "disp", i = ~ disp > 200, color = "yellow")
ft

mpg

cyl

disp

hp

drat

wt

qsec

vs

am

gear

carb

21

6

160

110

3.9

2.6

16

0

1

4

4

21

6

160

110

3.9

2.9

17

0

1

4

4

23

4

108

93

3.9

2.3

19

1

1

4

1

21

6

258

110

3.1

3.2

19

1

0

3

1

19

8

360

175

3.1

3.4

17

0

0

3

2

18

6

225

105

2.8

3.5

20

1

0

3

1

14

8

360

245

3.2

3.6

16

0

0

3

4

24

4

147

62

3.7

3.2

20

1

0

4

2

23

4

141

95

3.9

3.1

23

1

0

4

2

19

6

168

123

3.9

3.4

18

1

0

4

4

Text rotation

Text rotation is possible in flextable objects by using function rotate().

Argument rotation is mandatory and expects one of these values:

Argument align is used for cell content vertical alignment, it should be one of these values: “top”, “bottom” or “center”.

ft <- flextable(head(iris))
ft <- rotate(ft, rotation = "tbrl", align = "center", part = "header")
ft <- align(ft, align = "right", part = "header")
ft <- valign(ft, valign = "center", part = "header")
ft <- align(ft, align = "center", part = "body")

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

Line spacing

Line scaping can be defined with function line_spacing().

ft <- flextable(head(mtcars))
line_spacing(ft, space = 1)

mpg

cyl

disp

hp

drat

wt

qsec

vs

am

gear

carb

21

6

160

110

3.9

2.6

16

0

1

4

4

21

6

160

110

3.9

2.9

17

0

1

4

4

23

4

108

93

3.9

2.3

19

1

1

4

1

21

6

258

110

3.1

3.2

19

1

0

3

1

19

8

360

175

3.1

3.4

17

0

0

3

2

18

6

225

105

2.8

3.5

20

1

0

3

1

line_spacing(ft, space = 1.5)

mpg

cyl

disp

hp

drat

wt

qsec

vs

am

gear

carb

21

6

160

110

3.9

2.6

16

0

1

4

4

21

6

160

110

3.9

2.9

17

0

1

4

4

23

4

108

93

3.9

2.3

19

1

1

4

1

21

6

258

110

3.1

3.2

19

1

0

3

1

19

8

360

175

3.1

3.4

17

0

0

3

2

18

6

225

105

2.8

3.5

20

1

0

3

1

Borders

If no special formatting is needed, best is to use border_outer(), border_inner_h() and border_inner_v().

library(officer)
big_border = fp_border(color="orange", width = 2)
border_v = fp_border(color="gray")
border_h = fp_border(color="gray")

dat <- iris[c(1:2, 51:52, 101:102),]
ft <- flextable(dat)
ft <- border_remove(x = ft)
ft <- border_outer(ft, part="all", border = big_border )
ft <- border_inner_h(ft, part="all", border = border_h )
ft <- border_inner_v(ft, part="all", border = border_v )
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

7.0

3.2

4.7

1.4

versicolor

6.4

3.2

4.5

1.5

versicolor

6.3

3.3

6.0

2.5

virginica

5.8

2.7

5.1

1.9

virginica

When more control over borders formatting is necessary, the following functions can be used to add vertical or horizontal lines as borders:

dat <- iris[c(1:2, 51:52, 101:102),]
ft <- flextable(dat)
ft <- border_remove( ft )

big_b <- fp_border(color="gray70", width = 3)
std_b <- fp_border(color="orange", style = "dashed")

ft <- vline( ft, border = std_b, part = "all" )
ft <- vline_left( ft, border = big_b, part = "all" )
ft <- vline_right( ft, border = big_b, part = "all" )
ft <- hline( ft, border = std_b )
ft <- hline_bottom( ft, border = big_b )
ft <- hline_top( ft, border = big_b, part = "all" )
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

7.0

3.2

4.7

1.4

versicolor

6.4

3.2

4.5

1.5

versicolor

6.3

3.3

6.0

2.5

virginica

5.8

2.7

5.1

1.9

virginica

Conditional formatting

Conditional formatting can be made by using the selector arguments.

dat <- iris[c(1:2, 51:52, 101:102),]
ft <- flextable(dat)
ft <- fontsize(ft, size = 14, part = "all")
ft <- color(ft, i = ~ Sepal.Length < 5 & Petal.Length > 1.3, 
        j = ~ Petal.Width + Species, 
        color="red")
ft <- italic(ft, i = ~ Sepal.Length > 5)
ft <- bold(ft, i = 4, j = "Sepal.Length")
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

7.0

3.2

4.7

1.4

versicolor

6.4

3.2

4.5

1.5

versicolor

6.3

3.3

6.0

2.5

virginica

5.8

2.7

5.1

1.9

virginica

i and j arguments can be also standard R vectors:

row_id <- with(dat, Sepal.Length < 5 & Petal.Length > 1.3 )
col_id <- c("Petal.Width", "Species")

ft <- color(ft, i = row_id, j = col_id, color="red") 

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

7.0

3.2

4.7

1.4

versicolor

6.4

3.2

4.5

1.5

versicolor

6.3

3.3

6.0

2.5

virginica

5.8

2.7

5.1

1.9

virginica

Function style

The style function lets you style a selection of the flextable with several formatting properties. The function will apply formatting properties for text, paragraphs and table cells. It can be used to make the code less verbose.

Its main advantage is to let specify a set of formatting properties for a selection.

Package officer needs to be loaded, it comes with the following formatting properties that can be used as arguments:

library(officer)
def_par <- fp_par(text.align = "center")
def_text <- fp_text(font.size = 13, italic = TRUE)
def_text_header <- update(color="#c90000", def_text, bold = TRUE)

ft <- flextable(head(airquality))
ft

Ozone

Solar.R

Wind

Temp

Month

Day

41

190

7.4

67

5

1

36

118

8.0

72

5

2

12

149

12.6

74

5

3

18

313

11.5

62

5

4

14.3

56

5

5

28

14.9

66

5

6

ft <- style( x = ft, pr_p = def_par, pr_t = def_text, part = "all") ft

Ozone

Solar.R

Wind

Temp

Month

Day

41

190

7.4

67

5

1

36

118

8.0

72

5

2

12

149

12.6

74

5

3

18

313

11.5

62

5

4

14.3

56

5

5

28

14.9

66

5

6

ft <- style( x = ft, pr_t = def_text_header, part = "header") ft

Ozone

Solar.R

Wind

Temp

Month

Day

41

190

7.4

67

5

1

36

118

8.0

72

5

2

12

149

12.6

74

5

3

18

313

11.5

62

5

4

14.3

56

5

5

28

14.9

66

5

6

Theme functions

A set of theme functions are made available.

ft <- flextable(head(airquality))
ft <- add_header_row(ft, top = TRUE, 
                     values = c("measures", "time"), 
                     colwidths = c(4, 2))
ft <- align(ft, i = 1, align = "center", part = "header")
theme_booktabs(ft)

measures

time

Ozone

Solar.R

Wind

Temp

Month

Day

41

190

7.4

67

5

1

36

118

8.0

72

5

2

12

149

12.6

74

5

3

18

313

11.5

62

5

4

14.3

56

5

5

28

14.9

66

5

6

theme_alafoli(ft)

measures

time

Ozone

Solar.R

Wind

Temp

Month

Day

41

190

7.4

67

5

1

36

118

8.0

72

5

2

12

149

12.6

74

5

3

18

313

11.5

62

5

4

14.3

56

5

5

28

14.9

66

5

6

theme_vader(ft)

measures

time

Ozone

Solar.R

Wind

Temp

Month

Day

41

190

7.4

67

5

1

36

118

8.0

72

5

2

12

149

12.6

74

5

3

18

313

11.5

62

5

4

14.3

56

5

5

28

14.9

66

5

6

theme_box(ft)

measures

time

Ozone

Solar.R

Wind

Temp

Month

Day

41

190

7.4

67

5

1

36

118

8.0

72

5

2

12

149

12.6

74

5

3

18

313

11.5

62

5

4

14.3

56

5

5

28

14.9

66

5

6

theme_vanilla(ft)

measures

time

Ozone

Solar.R

Wind

Temp

Month

Day

41

190

7.4

67

5

1

36

118

8.0

72

5

2

12

149

12.6

74

5

3

18

313

11.5

62

5

4

14.3

56

5

5

28

14.9

66

5

6

theme_tron_legacy(ft)

measures

time

Ozone

Solar.R

Wind

Temp

Month

Day

41

190

7.4

67

5

1

36

118

8.0

72

5

2

12

149

12.6

74

5

3

18

313

11.5

62

5

4

14.3

56

5

5

28

14.9

66

5

6

You can also use them to create your theme.

my_theme <- function(x, ...) {
    x <- set_formatter_type(x, fmt_double = "%.02f", na_str="na")
    x <- set_table_properties(x, layout = "fixed")
    x <- border_remove(x)
    std_border <- fp_border(width = 1, color = "red")
    x <- border_outer(x, part="all", border = std_border )
    x <- border_inner_h(x, border = update(std_border, style = "dashed"), part="all")
    x <- border_inner_v(x, border = update(std_border, style = "dashed"), part="all")
    x
}
my_theme(ft)

measures

time

Ozone

Solar.R

Wind

Temp

Month

Day

41

190

7.40

67

5

1

36

118

8.00

72

5

2

12

149

12.60

74

5

3

18

313

11.50

62

5

4

14.30

56

5

5

28

14.90

66

5

6