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
.
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:
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.
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 |
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 |
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 |
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
).
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 |
# 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 |
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 |
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 |
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 |
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 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 scaping can be defined with function line_spacing()
.
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 |
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 |
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:
hline()
: set bottom borders (inner horizontal)vline()
: set right borders (inner vertical)hline_top()
: set the top border (outer horizontal)hline_bottom()
: set the bottom border (outer horizontal)vline_left()
: set the left border (outer vertical)vline_right()
: set the right border (outer vertical)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 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 |
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:
fp_text
fp_par
fp_cell
and fp_border
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |