Chapter 11 Programming
11.1 Part dimensions
Programming with flextable can be made easier by using a few functions:
-
nrow_part()
returns the number of lines in a part of flextable. -
ncol_keys()
returns the number of columns displayed.
For example, if you want to add an aggregation line below a sample and to format it differently from the sample rows :
library(flextable)
library(dplyr)
library(tibble)
dat_summary <- summarize(airquality, across(Ozone:Temp, ~ mean(.x, na.rm = TRUE))) %>%
add_column(label = "summary", .before = TRUE)
dat_summary
# label Ozone Solar.R Wind Temp
# 1 summary 42.12931 185.9315 9.957516 77.88235
dat_sample <- head(airquality) %>%
add_column(label = "sample", .before = TRUE)
dat_sample
# label Ozone Solar.R Wind Temp Month Day
# 1 sample 41 190 7.4 67 5 1
# 2 sample 36 118 8.0 72 5 2
# 3 sample 12 149 12.6 74 5 3
# 4 sample 18 313 11.5 62 5 4
# 5 sample NA NA 14.3 56 5 5
# 6 sample 28 NA 14.9 66 5 6
dat <- bind_rows(dat_sample, dat_summary)
ft <- flextable(dat, col_keys = colnames(airquality)) %>%
colformat_double(digits = 2, j = colnames(airquality)) %>%
theme_booktabs() %>%
bold(i = nrow_part(., part = "body")) %>%
footnote(i = nrow_part(., part = "body"), j = 1:4,
value = as_paragraph("Calculated mean"),
ref_symbols = c("(1)")) %>%
set_caption("a *weird* table summary")
ft
Ozone |
Solar.R |
Wind |
Temp |
Month |
Day |
---|---|---|---|---|---|
41.00 |
190.00 |
7.40 |
67.00 |
5 |
1 |
36.00 |
118.00 |
8.00 |
72.00 |
5 |
2 |
12.00 |
149.00 |
12.60 |
74.00 |
5 |
3 |
18.00 |
313.00 |
11.50 |
62.00 |
5 |
4 |
<na> |
<na> |
14.30 |
56.00 |
5 |
5 |
28.00 |
<na> |
14.90 |
66.00 |
5 |
6 |
42.13(1) |
185.93(1) |
9.96(1) |
77.88(1) |
<na> |
<na> |
(1)Calculated mean |
11.2 Function ‘before’
hline(ft, i = ~ before(label, "summary"),
border = fp_border_default(width = 2))
Ozone |
Solar.R |
Wind |
Temp |
Month |
Day |
---|---|---|---|---|---|
41.00 |
190.00 |
7.40 |
67.00 |
5 |
1 |
36.00 |
118.00 |
8.00 |
72.00 |
5 |
2 |
12.00 |
149.00 |
12.60 |
74.00 |
5 |
3 |
18.00 |
313.00 |
11.50 |
62.00 |
5 |
4 |
<na> |
<na> |
14.30 |
56.00 |
5 |
5 |
28.00 |
<na> |
14.90 |
66.00 |
5 |
6 |
42.13(1) |
185.93(1) |
9.96(1) |
77.88(1) |
<na> |
<na> |
(1)Calculated mean |
11.3 Looping over columns with compose
Function compose()
(or mk_par()
) can be used to define content of several columns in one call.
Argument value
can be a single as_paragraph()
call if use_dot=TRUE
. In that case, the call
need to refer to the column value as .
and not with its name. That way, multiple columns
can have their content updated with one single call.
If use_dot=TRUE
, value is evaluated within a data.frame augmented of a column named .
containing the jth
column.
The following illustration is made of two steps. The first one is only data transformation, we process the data for flextable by aggregating, plotting and pivoting:
dat <- nest(diamonds, data = -all_of(c("cut", "color"))) %>%
mutate(
gg =
lapply(
X = data,
FUN = function(subdat) {
ggplot(subdat, aes(x = x)) +
geom_density(color = "white") + theme_minimal() +
scale_x_continuous(limits = c(0, 11)) +
scale_y_continuous(limits = c(0, 1)) +
labs(x = "", y = "") + theme_void()
}
)
) %>%
select(-data) %>%
pivot_wider(
id_cols = cut,
names_from = color,
values_from = gg)
dat
# # A tibble: 5 × 8
# cut E I J H F G D
# <ord> <list> <list> <list> <list> <list> <list> <list>
# 1 Ideal <gg> <gg> <gg> <gg> <gg> <gg> <gg>
# 2 Premium <gg> <gg> <gg> <gg> <gg> <gg> <gg>
# 3 Good <gg> <gg> <gg> <gg> <gg> <gg> <gg>
# 4 Very Good <gg> <gg> <gg> <gg> <gg> <gg> <gg>
# 5 Fair <gg> <gg> <gg> <gg> <gg> <gg> <gg>
The second step is now straightforward, it format all columns but ‘cut’ as ggplot
of size “1 cm * 1 cm”. Note the usage of use_dot = TRUE
and .
in the call
to gg_chunk()
.
dat %>%
flextable() %>%
mk_par(
value = as_paragraph(
gg_chunk(., width = 1, height = 1, unit = "cm")),
j = ~ . - cut,
use_dot = TRUE) %>%
theme_tron() %>%
align(align = "center", part = "all") %>%
autofit()
cut |
E |
I |
J |
H |
F |
G |
D |
---|---|---|---|---|---|---|---|
Ideal |
|||||||
Premium |
|||||||
Good |
|||||||
Very Good |
|||||||
Fair |