La version 0.9.11 de flextable est arrivée récemment sur le CRAN. Elle contient deux fonctionnalités que nous sommes ravis de vous présenter :
- l’intégration avec patchwork : aligner un tableau et un graphique était
jusqu’ici un exercice laborieux. C’est désormais aussi simple que d’écrire
wrap_flextable(ft) + mon_graphique. - le support natif de Quarto avec
as_qmd(): il est désormais possible d’utiliser les références croisées, les captions et le markdown directement dans les cellules.
Intégration avec patchwork
Combiner et aligner un tableau et un graphique est devenu possible grâce à
‘patchwork’ qui offre un système sur lequel s’appuyer. C’est bien sûr ce dernier que
s’appuie la nouvelle fonction
wrap_flextable()
qui va permettre que les objets flextable s’intègrent
dans les compositions patchwork via les opérateurs +, | et /.
Les options sont détaillées dans la section Plotting flextable du “flextable-book”.
Pour illustrer, nous construisons un graphique “dumbbell” des statistiques de la Bundesliga accompagné d’un flextable (adapté de R Graph Gallery).
dataset <- data.frame(
team = c(
"FC Bayern Munchen", "SV Werder Bremen", "Borussia Dortmund",
"VfB Stuttgart", "Borussia M'gladbach", "Hamburger SV",
"Eintracht Frankfurt", "FC Schalke 04", "1. FC Koln",
"Bayer 04 Leverkusen"
),
matches = c(2000, 1992, 1924, 1924, 1898, 1866, 1856, 1832, 1754, 1524),
won = c(1206, 818, 881, 782, 763, 746, 683, 700, 674, 669),
lost = c( 363, 676, 563, 673, 636, 625, 693, 669, 628, 447)
)
dataset$win_pct <- dataset$won / dataset$matches * 100
dataset$loss_pct <- dataset$lost / dataset$matches * 100
dataset$team <- factor(dataset$team, levels = rev(dataset$team))
Le graphique “dumbbell” :
pal <- c(lost = "#EFAC00", won = "#28A87D")
df_long <- reshape(dataset, direction = "long",
varying = list(c("loss_pct", "win_pct")),
v.names = "pct", timevar = "type",
times = c("lost", "won"), idvar = "team"
)
p <- ggplot(df_long, aes(x = pct / 100, y = team)) +
stat_summary(
geom = "linerange", fun.min = "min", fun.max = "max",
linewidth = .7, color = "grey60"
) +
geom_point(aes(fill = type), size = 4, shape = 21,
stroke = .8, color = "white"
) +
scale_x_continuous(
labels = scales::percent,
expand = expansion(add = c(.02, .02))
) +
scale_y_discrete(name = NULL, guide = "none") +
scale_fill_manual(
values = pal,
guide = FALSE
) +
labs(x = NULL, fill = NULL) +
theme(
legend.position = "top",
legend.justification = "left",
panel.grid.minor = element_blank(),
panel.grid.major.y = element_blank()
)
p

Et le flextable correspondant :
ft_dat <- dataset[, c("matches", "loss_pct", "win_pct", "team")]
ft_dat$team <- as.character(ft_dat$team)
ft <- flextable(ft_dat) |>
border_remove() |>
bold(part = "header") |>
colformat_double(j = c("win_pct", "loss_pct"), digits = 1, suffix = "%") |>
set_header_labels(team = "Equipe", matches = "MJ", win_pct = "Gagnés", loss_pct = "Perdus") |>
color(color = c("#28A87D", "#EFAC00"), j = c("win_pct", "loss_pct")) |>
italic(j = "team", italic = TRUE, part = "all") |>
align(align = "right", part = "all") |>
autofit()
ft
MJ | Perdus | Gagnés | Equipe |
|---|---|---|---|
2,000 | 18.1% | 60.3% | FC Bayern Munchen |
1,992 | 33.9% | 41.1% | SV Werder Bremen |
1,924 | 29.3% | 45.8% | Borussia Dortmund |
1,924 | 35.0% | 40.6% | VfB Stuttgart |
1,898 | 33.5% | 40.2% | Borussia M'gladbach |
1,866 | 33.5% | 40.0% | Hamburger SV |
1,856 | 37.3% | 36.8% | Eintracht Frankfurt |
1,832 | 36.5% | 38.2% | FC Schalke 04 |
1,754 | 35.8% | 38.4% | 1. FC Koln |
1,524 | 29.3% | 43.9% | Bayer 04 Leverkusen |
Aligner les lignes avec flex_body
Quand flex_body = TRUE, les lignes du corps du tableau s’étirent
pour correspondre à la hauteur du panneau du graphique adjacent. Chaque
ligne du tableau s’aligne avec la catégorie correspondante sur l’axe y.
L’en-tête et le pied de page conservent leur taille fixe.
wrap_flextable(ft, flex_body = TRUE, just = "right") +
p +
plot_layout(widths = c(1.3, 2))

Les lignes du tableau sont parfaitement alignées avec les catégories du graphique, tableau et graphique ne font plus qu’un et le monde paraît magique.
Aligner les colonnes avec flex_cols
Quand flex_cols = TRUE, les colonnes de données s’étirent pour
remplir la largeur du panneau déterminée par le graphique adjacent.
Chaque colonne s’aligne avec la catégorie correspondante sur l’axe x.
cyl_mpg <- mtcars |>
mutate(
cyl = factor(cyl, levels = c(4, 6, 8), labels = c("4-cyl", "6-cyl", "8-cyl"))
) |>
summarise(
`mpg mean` = mean(mpg, na.rm = TRUE),
`mpg sd` = sd(mpg, na.rm = TRUE),
n = n(),
.by = c(cyl)
)
gg_bar <- ggplot(cyl_mpg, aes(cyl, `mpg mean`)) +
geom_col(fill = "#28A87D", width = 0.7) +
labs(x = "Cylindres", y = "MPG moyen") +
theme(axis.text.x = element_blank())
cyl_pivoted <- cyl_mpg |>
pivot_longer(
cols = where(is.numeric)
) |>
pivot_wider(
id_cols = name,
names_from = cyl, values_from = value,
names_sort = TRUE
)
cyl_pivoted
#> # A tibble: 3 × 4
#> name `4-cyl` `6-cyl` `8-cyl`
#> <chr> <dbl> <dbl> <dbl>
#> 1 mpg mean 26.7 19.7 15.1
#> 2 mpg sd 4.51 1.45 2.56
#> 3 n 11 7 14
set_flextable_defaults(border.color = "#28A87D")
ft_cyl <- flextable(cyl_pivoted) |>
set_header_labels(name = "") |>
align(align = "center", part = "all") |>
align(align = "right", j = 1, part = "all") |>
colformat_double(i = 1:2, digits = 2) |>
colformat_double(i = 3, digits = 0) |>
autofit()
ft_cyl
4-cyl | 6-cyl | 8-cyl | |
|---|---|---|---|
mpg mean | 26.66 | 19.74 | 15.10 |
mpg sd | 4.51 | 1.45 | 2.56 |
n | 11 | 7 | 14 |
wrap_flextable(ft_cyl, n_row_headers = 1, flex_cols = TRUE) /
gg_bar +
plot_layout(heights = c(1, 4))

Ici, chaque colonne du tableau correspond exactement à une barre du graphique, l’ensemble se lit comme une seule visualisation.
Quarto markdown dans les cellules
‘flextable’ ne permettait pas jusqu’alors l’utilisation du markdown dans les
cellules, avec comme conséquences que les cross-références, formules mathématiques, liens
n’étaient pas supportés au sein d’un document quarto. La nouvelle fonction as_qmd()
comble ce manque.
as_qmd() fonctionne avec les sorties HTML, PDF et Word.
Pour l’utiliser dans un projet Quarto, il faut d’abord installer
le filtre Lua compagnon avec use_flextable_qmd(), puis déclarer
le filtre dans le YAML du document :
filters:
- flextable-qmd
- at: post-render
path: _extensions/flextable-qmd/unwrap-float.lua
Voici un exemple de document Quarto qui utilise as_qmd() pour
des cross-références et du formatage markdown dans les cellules :
---
title: "Exemple flextable-qmd"
format: docx
filters:
- flextable-qmd
- at: post-render
path: _extensions/flextable-qmd/unwrap-float.lua
---
Voir le @tbl-example pour un apercu.
```{r}
#| label: tbl-example
#| tbl-cap: Tableau avec du markdown Quarto dans les cellules
library(flextable)
dat <- data.frame(
Fonctionnalite = c("Cross-ref", "Gras", "Maths", "Lien"),
Demo = c(
"Voir @tbl-example",
"**texte important**",
"$E = mc^2$",
"[ardata.fr](https://www.ardata.fr)"
),
stringsAsFactors = FALSE
)
flextable(dat) |>
mk_par(j = "Demo",
value = as_paragraph(as_qmd(Demo))) |>
autofit() |>
theme_vanilla()
```
Le résultat dans un document Word :
.
Le fichier produit est téléchargeable ici : quarto-as-qmd-fr.docx
N’hésitez pas à essayer ces nouvelles fonctionnalités.
Pour la liste complète des changements, consultez le changelog.
Suivez nous: - Sites recommandés: R-bloggers R weekly Twitter #rstats Jobs for R-users