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.100 | 3.500 | 1.400 | 0.200 | setosa |
4.900 | 3.000 | 1.400 | 0.200 | setosa |
4.700 | 3.200 | 1.300 | 0.200 | setosa |
4.600 | 3.100 | 1.500 | 0.200 | setosa |
5.000 | 3.600 | 1.400 | 0.200 | setosa |
5.400 | 3.900 | 1.700 | 0.400 | setosa |
Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species |
5.100 | 3.500 | 1.400 | 0.200 | setosa |
4.900 | 3.000 | 1.400 | 0.200 | setosa |
4.700 | 3.200 | 1.300 | 0.200 | setosa |
4.600 | 3.100 | 1.500 | 0.200 | setosa |
5.000 | 3.600 | 1.400 | 0.200 | setosa |
5.400 | 3.900 | 1.700 | 0.400 | setosa |
Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species |
5.100 | 3.500 | 1.400 | 0.200 | setosa |
4.900 | 3.000 | 1.400 | 0.200 | setosa |
4.700 | 3.200 | 1.300 | 0.200 | setosa |
4.600 | 3.100 | 1.500 | 0.200 | setosa |
5.000 | 3.600 | 1.400 | 0.200 | setosa |
5.400 | 3.900 | 1.700 | 0.400 | setosa |
Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species |
5.100 | 3.500 | 1.400 | 0.200 | setosa |
4.900 | 3.000 | 1.400 | 0.200 | setosa |
4.700 | 3.200 | 1.300 | 0.200 | setosa |
4.600 | 3.100 | 1.500 | 0.200 | setosa |
5.000 | 3.600 | 1.400 | 0.200 | setosa |
5.400 | 3.900 | 1.700 | 0.400 | setosa |
Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species |
5.100 | 3.500 | 1.400 | 0.200 | setosa |
4.900 | 3.000 | 1.400 | 0.200 | setosa |
4.700 | 3.200 | 1.300 | 0.200 | setosa |
4.600 | 3.100 | 1.500 | 0.200 | setosa |
5.000 | 3.600 | 1.400 | 0.200 | setosa |
5.400 | 3.900 | 1.700 | 0.400 | 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.100 | 3.500 | 1.400 | 0.200 | setosa |
4.900 | 3.000 | 1.400 | 0.200 | setosa |
4.700 | 3.200 | 1.300 | 0.200 | setosa |
4.600 | 3.100 | 1.500 | 0.200 | setosa |
5.000 | 3.600 | 1.400 | 0.200 | setosa |
5.400 | 3.900 | 1.700 | 0.400 | setosa |
Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species |
5.100 | 3.500 | 1.400 | 0.200 | setosa |
4.900 | 3.000 | 1.400 | 0.200 | setosa |
4.700 | 3.200 | 1.300 | 0.200 | setosa |
4.600 | 3.100 | 1.500 | 0.200 | setosa |
5.000 | 3.600 | 1.400 | 0.200 | setosa |
5.400 | 3.900 | 1.700 | 0.400 | setosa |
Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species |
5.100 | 3.500 | 1.400 | 0.200 | setosa |
4.900 | 3.000 | 1.400 | 0.200 | setosa |
4.700 | 3.200 | 1.300 | 0.200 | setosa |
4.600 | 3.100 | 1.500 | 0.200 | setosa |
5.000 | 3.600 | 1.400 | 0.200 | setosa |
5.400 | 3.900 | 1.700 | 0.400 | 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.100 | 3.500 | 1.400 | 0.200 | setosa |
4.900 | 3.000 | 1.400 | 0.200 | setosa |
4.700 | 3.200 | 1.300 | 0.200 | setosa |
4.600 | 3.100 | 1.500 | 0.200 | setosa |
5.000 | 3.600 | 1.400 | 0.200 | setosa |
5.400 | 3.900 | 1.700 | 0.400 | setosa |
Text rotation is possible in flextable objects but will only work correctly with Word and PowerPoint outputs (html output is not always correct). This is achieved 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 <- regulartable(head(iris))
ft <- rotate(ft, rotation = "tbrl", align = "top", part = "header")
ft <- theme_vanilla(ft)
ft <- autofit(ft)
# as autofit do not handle rotation, you will have
# to change manually header cells'height.
ft <- height(ft, height = 1, part = "header")
ft
Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species |
5.100 | 3.500 | 1.400 | 0.200 | setosa |
4.900 | 3.000 | 1.400 | 0.200 | setosa |
4.700 | 3.200 | 1.300 | 0.200 | setosa |
4.600 | 3.100 | 1.500 | 0.200 | setosa |
5.000 | 3.600 | 1.400 | 0.200 | setosa |
5.400 | 3.900 | 1.700 | 0.400 | setosa |
Borders properties can be defined with functions:
hline()
: set bottom borders of one or all parts of a flextable.hline_top()
: set top border of one or all parts of a flextable.hline_bottom()
: set bottom border of one or all parts of a flextable.vline()
: set right borders of one or all parts of a flextable.vline_left()
: set left border of one or all parts of a flextable.vline_right()
: set right border of one or all parts of a flextable.# remove all defined borders
myft <- border_remove( myft )
big_b <- fp_border(color="gray70", width = 2)
std_b <- fp_border(color="white")
myft <- vline( myft, border = std_b, part = "all" )
myft <- vline_left( myft, border = big_b, part = "all" )
myft <- vline_right( myft, border = big_b, part = "all" )
myft <- hline( myft, border = std_b )
myft <- hline_bottom( myft, border = big_b )
myft <- hline_top( myft, border = big_b, part = "all" )
myft
Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species |
5.100 | 3.500 | 1.400 | 0.200 | setosa |
4.900 | 3.000 | 1.400 | 0.200 | setosa |
4.700 | 3.200 | 1.300 | 0.200 | setosa |
4.600 | 3.100 | 1.500 | 0.200 | setosa |
5.000 | 3.600 | 1.400 | 0.200 | setosa |
5.400 | 3.900 | 1.700 | 0.400 | setosa |
Or when borders design is simple with:
border_outer()
: apply a border to outer cells of one or all parts of a flextable.border_inner()
: apply a border to inner cells of one or all parts of a flextable.std_b2 <- fp_border(color="white", style = "dashed")
# remove all defined borders
myft <- border_remove( myft )
myft <- border_outer( myft, border = big_b, part = "all" )
myft <- border_inner_h( myft, border = std_b, part = "all" )
myft <- border_inner_v( myft, border = std_b2, part = "all" )
myft
Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species |
5.100 | 3.500 | 1.400 | 0.200 | setosa |
4.900 | 3.000 | 1.400 | 0.200 | setosa |
4.700 | 3.200 | 1.300 | 0.200 | setosa |
4.600 | 3.100 | 1.500 | 0.200 | setosa |
5.000 | 3.600 | 1.400 | 0.200 | setosa |
5.400 | 3.900 | 1.700 | 0.400 | setosa |
Conditional formatting can be made by using the selector arguments.
myft <- color(myft, i = ~ Sepal.Length < 5 & Petal.Length > 1.3,
j = ~ Petal.Width + Species,
color="red")
myft <- bg(myft, j = 1, bg = "#D3C994", part = "header")
myft <- italic(myft, i = ~ Sepal.Length > 5)
myft <- bold(myft, i = 4, j = "Sepal.Length")
myft
Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species |
5.100 | 3.500 | 1.400 | 0.200 | setosa |
4.900 | 3.000 | 1.400 | 0.200 | setosa |
4.700 | 3.200 | 1.300 | 0.200 | setosa |
4.600 | 3.100 | 1.500 | 0.200 | setosa |
5.000 | 3.600 | 1.400 | 0.200 | setosa |
5.400 | 3.900 | 1.700 | 0.400 | setosa |
i
and j
arguments can be also standard R vectors:
row_id <- with(head(iris), Sepal.Length < 5 & Petal.Length > 1.3 )
col_id <- c("Petal.Width", "Species")
myft <- color(myft, i = row_id, j = col_id, color="red")
myft
Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species |
5.100 | 3.500 | 1.400 | 0.200 | setosa |
4.900 | 3.000 | 1.400 | 0.200 | setosa |
4.700 | 3.200 | 1.300 | 0.200 | setosa |
4.600 | 3.100 | 1.500 | 0.200 | setosa |
5.000 | 3.600 | 1.400 | 0.200 | setosa |
5.400 | 3.900 | 1.700 | 0.400 | setosa |
The style
function lets you style a selection of the flextable with several formatting properties.
It main advantage is to let specify a set of formatting properties for a selection.
Package officer needs to be loaded, it provides the following formatting properties:
fp_text
fp_par
fp_cell
and fp_border
library(officer)
def_cell <- fp_cell(border = fp_border(color="#00C9C9"))
def_par <- fp_par(text.align = "center")
def_text <- fp_text(color="#999999", italic = TRUE)
def_text_header <- update(color="black", def_text, bold = TRUE)
ft <- regulartable(head(mtcars, n = 10 ))
ft <- style( ft, pr_c = def_cell, pr_p = def_par, pr_t = def_text, part = "all")
ft
mpg | cyl | disp | hp | drat | wt | qsec | vs | am | gear | carb |
21.000 | 6.000 | 160.000 | 110.000 | 3.900 | 2.620 | 16.460 | 0.000 | 1.000 | 4.000 | 4.000 |
21.000 | 6.000 | 160.000 | 110.000 | 3.900 | 2.875 | 17.020 | 0.000 | 1.000 | 4.000 | 4.000 |
22.800 | 4.000 | 108.000 | 93.000 | 3.850 | 2.320 | 18.610 | 1.000 | 1.000 | 4.000 | 1.000 |
21.400 | 6.000 | 258.000 | 110.000 | 3.080 | 3.215 | 19.440 | 1.000 | 0.000 | 3.000 | 1.000 |
18.700 | 8.000 | 360.000 | 175.000 | 3.150 | 3.440 | 17.020 | 0.000 | 0.000 | 3.000 | 2.000 |
18.100 | 6.000 | 225.000 | 105.000 | 2.760 | 3.460 | 20.220 | 1.000 | 0.000 | 3.000 | 1.000 |
14.300 | 8.000 | 360.000 | 245.000 | 3.210 | 3.570 | 15.840 | 0.000 | 0.000 | 3.000 | 4.000 |
24.400 | 4.000 | 146.700 | 62.000 | 3.690 | 3.190 | 20.000 | 1.000 | 0.000 | 4.000 | 2.000 |
22.800 | 4.000 | 140.800 | 95.000 | 3.920 | 3.150 | 22.900 | 1.000 | 0.000 | 4.000 | 2.000 |
19.200 | 6.000 | 167.600 | 123.000 | 3.920 | 3.440 | 18.300 | 1.000 | 0.000 | 4.000 | 4.000 |
mpg | cyl | disp | hp | drat | wt | qsec | vs | am | gear | carb |
21.000 | 6.000 | 160.000 | 110.000 | 3.900 | 2.620 | 16.460 | 0.000 | 1.000 | 4.000 | 4.000 |
21.000 | 6.000 | 160.000 | 110.000 | 3.900 | 2.875 | 17.020 | 0.000 | 1.000 | 4.000 | 4.000 |
22.800 | 4.000 | 108.000 | 93.000 | 3.850 | 2.320 | 18.610 | 1.000 | 1.000 | 4.000 | 1.000 |
21.400 | 6.000 | 258.000 | 110.000 | 3.080 | 3.215 | 19.440 | 1.000 | 0.000 | 3.000 | 1.000 |
18.700 | 8.000 | 360.000 | 175.000 | 3.150 | 3.440 | 17.020 | 0.000 | 0.000 | 3.000 | 2.000 |
18.100 | 6.000 | 225.000 | 105.000 | 2.760 | 3.460 | 20.220 | 1.000 | 0.000 | 3.000 | 1.000 |
14.300 | 8.000 | 360.000 | 245.000 | 3.210 | 3.570 | 15.840 | 0.000 | 0.000 | 3.000 | 4.000 |
24.400 | 4.000 | 146.700 | 62.000 | 3.690 | 3.190 | 20.000 | 1.000 | 0.000 | 4.000 | 2.000 |
22.800 | 4.000 | 140.800 | 95.000 | 3.920 | 3.150 | 22.900 | 1.000 | 0.000 | 4.000 | 2.000 |
19.200 | 6.000 | 167.600 | 123.000 | 3.920 | 3.440 | 18.300 | 1.000 | 0.000 | 4.000 | 4.000 |
By default, the displayed content of each cell will be the result of a simple formatting. The content can also be formatted as the result of an interpolation.
First the columns functions, they will define the formatting for each column.
When working with a regulartable
, user can have the control of the formatting function by using set_formatter
.
When working with a flextable
, user can have the control of the formatting function by using display
. The function enable the control of format at the cell level. It can also be used to mixed chunks of text with various text formats and images.
Theses are high level functions that should satisfy most of the usual needs. They can be used to define the formatting of one or more columns.
Each accept a prefix
and suffix
argument that can be used to add a currency symbol for example. Also they all have na_str
argument (defaut to “”), the string to use when data are not available.
colformat_num()
with arguments digits
and big.mark
colformat_int()
with arguments big.mark
colformat_char()
dat <- head(mtcars, n = 10)
dat[3:7, 1] <- NA
dat[, 2] <- dat[, 6] * 1000000
ft <- regulartable(dat)
num_keys <- c("mpg", "disp", "drat", "wt", "qsec")
int_keys <- c("cyl", "hp", "vs", "am", "gear", "carb")
ft <- colformat_num(x = ft, col_keys = num_keys, big.mark = ",", digits = 2, na_str = "missing")
ft <- colformat_int(x = ft, col_keys = int_keys, big.mark = ",")
autofit(ft)
mpg | cyl | disp | hp | drat | wt | qsec | vs | am | gear | carb |
21.00 | 2,620,000 | 160.00 | 110 | 3.90 | 2.62 | 16.46 | 0 | 1 | 4 | 4 |
21.00 | 2,875,000 | 160.00 | 110 | 3.90 | 2.88 | 17.02 | 0 | 1 | 4 | 4 |
missing | 2,320,000 | 108.00 | 93 | 3.85 | 2.32 | 18.61 | 1 | 1 | 4 | 1 |
missing | 3,215,000 | 258.00 | 110 | 3.08 | 3.21 | 19.44 | 1 | 0 | 3 | 1 |
missing | 3,440,000 | 360.00 | 175 | 3.15 | 3.44 | 17.02 | 0 | 0 | 3 | 2 |
missing | 3,460,000 | 225.00 | 105 | 2.76 | 3.46 | 20.22 | 1 | 0 | 3 | 1 |
missing | 3,570,000 | 360.00 | 245 | 3.21 | 3.57 | 15.84 | 0 | 0 | 3 | 4 |
24.40 | 3,190,000 | 146.70 | 62 | 3.69 | 3.19 | 20.00 | 1 | 0 | 4 | 2 |
22.80 | 3,150,000 | 140.80 | 95 | 3.92 | 3.15 | 22.90 | 1 | 0 | 4 | 2 |
19.20 | 3,440,000 | 167.60 | 123 | 3.92 | 3.44 | 18.30 | 1 | 0 | 4 | 4 |
When working with regulartable
, it is possible to define the functions that will be used to format the data.frame values into strings. set_formatter
set column formatter functions.
Note
set_formatter
only works withregulartable
objects, usedisplay
forflextable
objects.
ft <- regulartable(head(mtcars, n = 10 ),
col_keys = c("gear", "mpg", "qsec"))
ft <- set_formatter(ft,
mpg = function(x) sprintf("%.04f", x),
gear = function(x) sprintf("%.0f gears", x)
)
ft <- theme_booktabs(ft)
ft <- autofit(ft)
ft
gear | mpg | qsec |
4 gears | 21.0000 | 16.460 |
4 gears | 21.0000 | 17.020 |
4 gears | 22.8000 | 18.610 |
3 gears | 21.4000 | 19.440 |
3 gears | 18.7000 | 17.020 |
3 gears | 18.1000 | 20.220 |
3 gears | 14.3000 | 15.840 |
4 gears | 24.4000 | 20.000 |
4 gears | 22.8000 | 22.900 |
4 gears | 19.2000 | 18.300 |
flextable
content is defined with display
function.
It lets user control the formated content at the cell level of the table. It is possible to define a content for a row subset and a column as well as on the whole column. One can mix images and text (but not with PowerPoint because PowerPoint can not do it).
Note
display
only works withflextable
objects, useset_formatter
forregulartable
objects.
Below the starting point of next illustrations:
myft <- flextable( head(mtcars),
col_keys = c("am", "separator", "gear", "mpg", "drat", "qsec" ))
myft <- bold(myft, part = "header")
myft <- border(myft, border = fp_border( width = 0),
border.top = fp_border(), border.bottom = fp_border(),
part = "all")
myft <- align(myft, align = "right", part = "all" )
myft <- border(myft, j = ~ separator, border = fp_border(width=0), part = "all")
myft <- width(myft, j = ~ separator, width = .1)
myft
am | gear | mpg | drat | qsec | |
1.000 | 4.000 | 21.000 | 3.900 | 16.460 | |
1.000 | 4.000 | 21.000 | 3.900 | 17.020 | |
1.000 | 4.000 | 22.800 | 3.850 | 18.610 | |
0.000 | 3.000 | 21.400 | 3.080 | 19.440 | |
0.000 | 3.000 | 18.700 | 3.150 | 17.020 | |
0.000 | 3.000 | 18.100 | 2.760 | 20.220 |
The function requires argument pattern
which is a string template inspired by mustaches. The string will be expanded with tags using values provided in formatters
argument; tags can eventually be formatted with fprops
argument.
The following example shows how to control the format of displayed values and how to associate them with specific text formatting properties (bold red text):
myft <- display( myft, col_key = "mpg", pattern = "{{mpg}}",
formatters = list(mpg ~ sprintf("%.01f", mpg) ),
fprops = list(mpg = fp_text(color = "red", italic = TRUE) )
)
myft
am | gear | mpg | drat | qsec | |
1.000 | 4.000 | 21.0 | 3.900 | 16.460 | |
1.000 | 4.000 | 21.0 | 3.900 | 17.020 | |
1.000 | 4.000 | 22.8 | 3.850 | 18.610 | |
0.000 | 3.000 | 21.4 | 3.080 | 19.440 | |
0.000 | 3.000 | 18.7 | 3.150 | 17.020 | |
0.000 | 3.000 | 18.1 | 2.760 | 20.220 |
With that system, it’s easy to concatenate multiple values:
myft <- display( myft, i = ~ drat > 3.6,
col_key = "mpg", pattern = "{{mpg}} with {{carb}}",
formatters = list(mpg ~ sprintf("%.01f", mpg),
carb ~ sprintf("# %.0f carb.", carb) ),
fprops = list(mpg = fp_text(color = "#CC55CC", bold = TRUE) )
)
myft <- autofit(myft)
myft
am | gear | mpg | drat | qsec | |
1.000 | 4.000 | 21.0 with # 4 carb. | 3.900 | 16.460 | |
1.000 | 4.000 | 21.0 with # 4 carb. | 3.900 | 17.020 | |
1.000 | 4.000 | 22.8 with # 1 carb. | 3.850 | 18.610 | |
0.000 | 3.000 | 21.4 | 3.080 | 19.440 | |
0.000 | 3.000 | 18.7 | 3.150 | 17.020 | |
0.000 | 3.000 | 18.1 | 2.760 | 20.220 |
Or to define specific title headers:
myft <- display( myft, col_key = "mpg",
part = "header",
pattern = "Miles/(US) gallon {{my_message}}",
formatters = list(
my_message ~ sprintf("* with num of carb.")
),
fprops = list(
my_message = fp_text(color = "gray", vertical.align = "superscript")
)
)
myft <- autofit(myft)
myft
am | gear | Miles/(US) gallon * with num of carb. | drat | qsec | |
1.000 | 4.000 | 21.0 with # 4 carb. | 3.900 | 16.460 | |
1.000 | 4.000 | 21.0 with # 4 carb. | 3.900 | 17.020 | |
1.000 | 4.000 | 22.8 with # 1 carb. | 3.850 | 18.610 | |
0.000 | 3.000 | 21.4 | 3.080 | 19.440 | |
0.000 | 3.000 | 18.7 | 3.150 | 17.020 | |
0.000 | 3.000 | 18.1 | 2.760 | 20.220 |
Function display
supports images insertion. Use function as_image
within formatters
argument.
img.file <- file.path( R.home("doc"), "html", "logo.jpg" )
myft <- display( myft, i = ~ qsec > 18, col_key = "qsec",
pattern = "blah blah {{r_logo}} {{qsec}}",
formatters = list(
r_logo ~ as_image(qsec, src = img.file, width = .20, height = .15),
qsec ~ sprintf("qsec: %.1f", qsec) ),
fprops = list(qsec = fp_text(color = "orange", vertical.align = "superscript"))
)
myft <- autofit(myft)
myft
am | gear | Miles/(US) gallon * with num of carb. | drat | qsec | |
1.000 | 4.000 | 21.0 with # 4 carb. | 3.900 | 16.460 | |
1.000 | 4.000 | 21.0 with # 4 carb. | 3.900 | 17.020 | |
1.000 | 4.000 | 22.8 with # 1 carb. | 3.850 | blah blah | |
0.000 | 3.000 | 21.4 | 3.080 | blah blah | |
0.000 | 3.000 | 18.7 | 3.150 | 17.020 | |
0.000 | 3.000 | 18.1 | 2.760 | blah blah |