Table layout

flextable layout can be managed with few functions.

library(flextable)
library(officer)

Cell merging

vertical merging

merge_v will merge adjacent duplicated cells for each column of the selection.

select_columns <- c("Species", "Petal.Length", "Petal.Width")
myft <- regulartable(iris[46:55,], col_keys = select_columns)
myft <- merge_v(myft, ~ Species + Petal.Width )
myft

Species

Petal.Length

Petal.Width

setosa

1.400

0.300

1.600

0.200

1.400

1.500

1.400

versicolor

4.700

1.400

4.500

1.500

4.900

4.000

1.300

4.600

1.500

horizontal merging

merge_h will merge adjacent duplicated cells for each row of the selection.

select_columns <- c("Species", "Petal.Length", "Petal.Width")
myft <- regulartable(head(mtcars, n = 10 ) )
myft <- merge_h(myft)
# and add borders
myft <- border(myft, border = fp_border(), part = "all")
myft

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

21.000

6.000

160.000

110.000

3.900

2.875

17.020

0.000

1.000

4.000

22.800

4.000

108.000

93.000

3.850

2.320

18.610

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

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

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

general merging function

select_columns <- c("Species", "Petal.Length", "Petal.Width")
myft <- regulartable(head(mtcars, n = 6 ) )
myft <- merge_at( myft, i = 1:3, j = 1:3)
myft <- border(myft, border = fp_border(), part = "all")
myft

mpg

cyl

disp

hp

drat

wt

qsec

vs

am

gear

carb

21.000

110.000

3.900

2.620

16.460

0.000

1.000

4.000

4.000

110.000

3.900

2.875

17.020

0.000

1.000

4.000

4.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

delete merging informations

If you want to get rid of all merging (i.e. for development purposes), use merge_none:

merge_none(myft)

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

Manage headers

col_keys

Parameter col_keys define the variables to display and their order.

data <- iris[c(1:3, 51:53, 101:104),]
myft <- regulartable(data, col_keys = c("Species", "Sepal.Length", "Petal.Length") )
theme_booktabs(myft)

Species

Sepal.Length

Petal.Length

setosa

5.100

1.400

setosa

4.900

1.400

setosa

4.700

1.300

versicolor

7.000

4.700

versicolor

6.400

4.500

versicolor

6.900

4.900

virginica

6.300

6.000

virginica

5.800

5.100

virginica

7.100

5.900

virginica

6.300

5.600

If parameter col_keys has variables that are not existing in the dataset, they will be considered as blank columns and can be used as separators (in fact they can be use as you want, there is only no mapping of data associated).

myft <- regulartable(
data = data,
col_keys = c("Species", "col_1", "Sepal.Length", "Petal.Length") )
myft <- theme_vanilla(myft)
myft <- autofit(myft)
myft <- border(myft, j = 2,
border = fp_border(width=0), part = "all")

col_keys default values are the names of the data.frame used to fill the flextable.

Change labels

Use set_header_labels to replace labels of the bottom row of header.

ft <- regulartable( head( iris ) )
ft <- set_header_labels(ft, Sepal.Length = "Sepal",
Sepal.Width = "Sepal", Petal.Length = "Petal",
Petal.Width = "Petal", Species = "Species" )
ft <- theme_vanilla(ft)
ft <- autofit(ft)
ft

Sepal

Sepal

Petal

Petal

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

add a row of labels

Use add_header to add an header row.

ft <- add_header(ft, Sepal.Length = "length",
Sepal.Width = "width", Petal.Length = "length",
Petal.Width = "width", Species = "Species", top = FALSE )
ft <- theme_vanilla(ft)
ft <- autofit(ft)
ft

Sepal

Sepal

Petal

Petal

Species

length

width

length

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

ft <- add_header(ft, Sepal.Length = "Inches",
Sepal.Width = "Inches", Petal.Length = "Inches",
Petal.Width = "Inches", Species = "Species", top = TRUE )
# merge identical cells
ft <- merge_h(ft, part = "header")
ft <- merge_v(ft, part = "header")
ft <- theme_vanilla(ft)
ft <- autofit(ft)
ft

Inches

Species

Sepal

Petal

length

width

length

width

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

Define headers with a reference table

Use set_header_df with a data.frame as parameter. Columns of the dataset will be transposed and joined using a key column.

Input dataset

Variable col_keys define key values to match with flextable column keys (defined by argument col_keys of flextable function).

This key column will not be displayed. Other variables will added as rows. Note that variables names are not displayed.

typology <- data.frame(
col_keys = c( "Sepal.Length", "Sepal.Width", "Petal.Length",
"Petal.Width", "Species" ),
type = c("double", "double", "double", "double", "factor"),
what = c("Sepal", "Sepal", "Petal", "Petal", "Species"),
measure = c("Length", "Width", "Length", "Width", "Species"),
stringsAsFactors = FALSE )
autofit( theme_vanilla(flextable(typology)) )

col_keys

type

what

measure

Sepal.Length

double

Sepal

Length

Sepal.Width

double

Sepal

Width

Petal.Length

double

Petal

Length

Petal.Width

double

Petal

Width

Species

factor

Species

Species

Add the dataset as header rows

Then use set_header_df with parameter key that specifies name of the column used to permform the join. Order of columns matters, first column will be first row, second one will be the second row, etc.

ft <- regulartable( head( iris ) )
ft <- set_header_df( ft, mapping = typology, key = "col_keys" )
ft <- merge_h(ft, part = "header")
ft <- merge_v(ft, part = "header")
ft <- theme_vanilla(ft)
ft <- autofit(ft)
ft

double

factor

Sepal

Petal

Species

Length

Width

Length

Width

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

Cell widths and heights

The default sizes of flextable columns and rows are calculated with a simple algorithm. This will drive to inadequate rows heights and columns widths in some cases (when data values are wider than headers). You can use function dim to get flextable dimensions.

ft_base <- regulartable(head(iris))
ft_base <- theme_tron_legacy(ft_base)
ft_base

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

dim(ft_base)
#> $widths
#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> 0.75 0.75 0.75 0.75 0.75
#>
#> $heights
#> [1] 0.25 0.25 0.25 0.25 0.25 0.25 0.25

Pretty dimensions

Function dim_pretty is computing optimized widths and heights.

dim_pretty(ft_base)
#> $widths
#> [1] 0.9460630 0.8688196 0.9074752 0.8302318 0.5991121
#>
#> $heights
#> [1] 0.2044180 0.1756637 0.1756637 0.1756637 0.1756637 0.1756637 0.1756637

Adjusts automatically cell widths and heights

Function autofit optimises widths and heights of the flextable. This function is almost always to be called once when using flextable objects, it makes compact tables.

ft <- autofit(ft_base, add_w = 0, add_h = 0)
dim(ft)
#> $widths
#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> 0.9460630 0.8688196 0.9074752 0.8302318 0.5991121
#>
#> $heights
#> [1] 0.2044180 0.1756637 0.1756637 0.1756637 0.1756637 0.1756637 0.1756637
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

Adjusts manually cell widths and heights

Function width() and height() let you control dimensions of a flextable. height_all() is an helper function to set the same height to each part of the table.

ft <- autofit(ft_base)
ft <- width(ft, j = ~ Species, width = 2)
ft <- height_all( ft, height = .4 )
ft <- height( ft, i = 3, height = 1 )
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