flextable layout can be managed with few functions.
library(flextable)
library(officer)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 )
myftSpecies | 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 |
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")
myftmpg | 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 | |
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")
myftmpg | 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 |
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 |
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.
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)
ftSepal | 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 |
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)
ftSepal | 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)
ftInches | 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 |
Use set_header_df with a data.frame as parameter. Columns of the dataset will be transposed and joined using a key column.
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 |
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)
ftdouble | 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 |
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_baseSepal.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.25Function dim_pretty is computing optimized widths and heights.
dim_pretty(ft_base)
#> $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.1756637Function 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
ftSepal.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 |
Function width and height let you control dimensions of a flextable.
ft <- autofit(ft_base)
ft <- width(ft, j = ~ Species, width = 2)
ft <- height( ft, height = .4, part = "all" )
ftSepal.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 |