Les tableaux ont toujours été utilisés pour présenter des données, des résultats d’analyses statistiques, quand on doit voir les chiffres noir sur blanc. Quand on code en R, on n’en a pas particulièrement besoin, mais dès qu’on parle de reporting ou de PDF via RMarkdown, la question de la représentation des tables se pose souvent, et elles sont souvent combinées à des éléments de dataviz. Quelques packages y sont dédiés, petit tour d’horizon…
Sommaire
Tables statiques dans RMarkdown pour un document PDF
Dans un souci de lisibilité de cet article, je ne vous présenterai ici que les 6 premières lignes du jeu de données iris
et mtcars
. On utilisera aussi les données starwars
du package {dplyr}
:
library(dplyr)
data("starwars")
Quand on souhaite restituer son travail à l’aide de rapports automatisés, on peut le faire depuis R grâce à RMarkdown. Vous vous souvenez, on vous parlait de {bookdown} il n’y a pas si longtemps dans “Rédiger avec bookdown : pourquoi ? comment ?”. Et pour sortir un beau document PDF tout plein de graphes R et de tables, vous pouvez spécifier l’affichage des tables notamment dans l’en-tête YAML de votre fichier RMarkdown :
output:
pdf_document:
df_print: default
On obtient :
head(iris)
output:
pdf_document:
df_print: kable
(ce qui est équivalent à utiliser knitr::kable()
dans un chunk)
La table précédente devient :
La fonction kable()
et le package {kableExtra}
Ce package nous permet de créer des tables complexes, tout en y appliquant des styles. Il importe le symbole pipe %>%
de {magrittr}
: on peut ajouter des “couches” à une sortie kable()
.
# Installation de la library
install.packages("kableExtra")
# Chargement des libraries
library(knitr)
library(kableExtra)
La fonction kable()
pour un affichage de tableaux simples et efficaces
Quand on crée une table en Rmakdown dans un format PDF, on utilise une distribution LaTeX, dont le style usuel est plutôt affreux :
head(iris) %>%
kable(format = "latex")
booktable
à TRUE
, le résultat est un peu plus satisfaisant, on revient à l’appel simple de la fonction kable()
:
head(iris) %>%
kable(format = "latex", booktable = TRUE)
caption
de la fonction kable()
:
head(iris) %>%
kable(format = "latex", booktable = TRUE, caption = "Ma table")
Donner du style à vos tableaux avec kable_styling()
Ok, donc avec la fonction kable()
, on ne peut pas vraiment aller plus loin. C’est là qu’entre en jeu le package {kableExtra}
, dont la fonction kable_styling()
permet de styliser un peu notre table, comme par exemple via le paramètre latex_options
:
head(iris) %>%
kable("latex", booktabs = T)%>%
kable_styling(latex_options = "striped")
HOLD_position
, je peux ajouter un titre à ma table et faire en sorte qu’elle reste à l’endroit exact où je l’ai créée :
head(iris) %>%
kable("latex", booktabs = T, caption = "Ma table")%>%
kable_styling(latex_options = c("striped", "HOLD_position"))
Dans le cas où j’ai une table avec un grand nombre de colonnes, je peux utiliser l’option scale_down
qui va permettre un ajustement de la table à la taille de la page. Prenons par exemple les données starwars
du package {dplyr}
:
library(dplyr)
data("starwars")
star2 <- starwars %>%
select(-(films:starships)) %>%
head()
Sans l’option, toutes les colonnes ne s’affichent pas :
star2 %>%
kable("latex", booktabs = T)%>%
kable_styling(latex_options = "striped")
scale_down
:
star2 %>%
kable("latex", booktabs = T)%>%
kable_styling(latex_options = c("striped", "scale_down"))
repeat_header
et le paramètre longtable
:
iris %>%
kable("latex", longtable = TRUE, booktabs = TRUE) %>%
kable_styling(latex_options =c("repeat_header"))
Un autre paramètre intéressant de la fonction kable_styling()
: full_width
, qui quand il est mis à TRUE
permet d’étendre une table sur toute la largeur de la page :
head(iris) %>%
kable("latex", booktabs = T)%>%
kable_styling(full_width = TRUE)
On peut également noter le paramètre font_size
qui permet d’indiquer la taille des caractères de la table :
head(iris) %>%
kable("latex", booktabs = T) %>%
kable_styling(font_size = 6)
Des colonnes et des lignes stylées, en couleur, italique, gras, …
Et si on ajoutait un peu de couleurs maintenant ? et un peu plus de style ? Prenons les données star2
. Je souhaite mettre la colonne name
en gras, la colonne species
en rouge, la première ligne en italique, blanc et sur fond noir, changer l’orientation et la couleur des noms de colonnes :
- la fonction
column_spec
permet de spécifier le style d’une ou plusieurs colonnes - la fonction
row_spec
permet de spécifier le style d’une ou plusieurs lignes
head(star2) %>%
kable("latex", booktabs = TRUE) %>%
kable_styling(latex_options = "scale_down") %>%
column_spec(1, bold = TRUE) %>%
column_spec(11, color = "red") %>%
row_spec(1, bold = T, color = "white", background = "black", italic = TRUE) %>%
row_spec(0, angle = 45, bold = TRUE, color = spec_color(1:11, end = 0.9, option = "A", direction = -1))
Complexifier la structure avec de multiples en-tête et des cellules fusionnées
{kableExtra}
permet aussi de réaliser des tables un peu plus complexes en termes de structure :
add_header_above()
permet de grouper les colonnes et d’ajouter une seconde ligne contenant le nom des groupes
Par exemple, avec les données iris :
head(iris) %>%
kable("latex", booktabs = TRUE) %>%
kable_styling(latex_options = "striped") %>%
add_header_above(c("Sepal" = 2, "Petal" = 2, " " = 1), italic = TRUE)
pack_rows()
permet de grouper les lignes
Par exemple avec les données mtcars :
mtcars[1:10, 1:6] %>%
kable("latex", booktabs = T) %>%
kable_styling() %>%
pack_rows("Group 1", 4, 7) %>%
pack_rows("Group 2", 8, 10)
collapse_rows()
:
mtcars[1:10, 1:6] %>%
mutate(Groupe = c(rep("", 3), rep("Group 1", 4), rep("Group 2", 3)),
name = rownames(.), .before = mpg) %>%
kable("latex", booktabs = T) %>%
collapse_rows(columns = 1, valign = "middle", latex_hline = "major")
Ajout de notes de bas de tableau
On peut également **ajouter des notes en bas du tableau*, via la fonction footnote()
:
head(iris) %>%
kable("latex", booktabs = TRUE) %>%
footnote(general = "Commentaire général de la table",
number = c("note 1; ", "note 2; "),
alphabet = c("note A; ", "note B; "),
symbol = c("symbole 1; ", "symbole 2"),
title_format = c("italic", "underline"))
Le package {gt}
pour formater vos tableaux
{gt}
, pour great table. C’est un package relativement récent, puissant et simple d’utilisation. La fonction de base, gt()
, appelée sans paramètres autres que le jeu de données, nous donne le même rendu que la fonction kable()
du package {knitr}
:
library(gt)
head(iris) %>%
gt()
Les éléments d’une table gt
En-tête, notes de bas de tableau, pied de page et sources
Tout comme avec le package {kableExtra}
, il est possible de construire nos tables via le pipe %>%
. Les éléments extérieurs à la table tels que titre, sous-titre, footnote et sources peuvent être ajoutés via les fonctions de type tab_X()
:
tab_header()
pour le titre et le sous-titretab_footnote()
pour les notes de pied de page, appelée pour chaque référence à un ou plusieurs éléments de la tabletab_source_note
pour les sources, cette fonction peut être appelée autant de fois que l’on a de sources
Par exemple :
head(iris) %>%
gt() %>%
tab_header(title = "Données Iris",
subtitle = "Premières lignes"
) %>%
tab_footnote(footnote = "Colonne Species",
locations = cells_column_labels(
columns = vars(Species))) %>%
tab_source_note("Source : package datasets")
md()
, ou du HTML via la fonction html()
:
head(iris) %>%
gt() %>%
tab_header(title = md("Données **Iris**"),
subtitle = md("*Premières lignes*")) %>%
tab_footnote(footnote = "Colonne Species",
locations = cells_column_labels(
columns = vars(Species))) %>%
tab_source_note(md("Source : package `{datasets}`"))
locations
de la fonction tab_footnote()
, avec :
cells_body()
: prend en argumentscolumns
etrows
qui peuvent être des vecteurs de noms de colonnes et de lignes (char
), des vecteurs d’indices, ou une fonctions de sélection commestart_with()
,ends_with()
,contains()
, …cells_column_labels()
pour cibler les noms des colonnescells_row_groups()
- …
Le “stub” pour gérer les titres et les groupes de lignes
C’est toute la partie qui concerne les noms de lignes, dans la zone gauche du tableau. Un moyen simple de générer cette zone consiste à le déclarer lors de l’appel à la fonction gt()
via le paramètre rowname_col
. La fonction tab_stubhead()
permet quant à elle d’ajouter un label aux noms de lignes. Par exemple avec les données mtcars
:
mtcars %>%
mutate(name = rownames(.)) %>%
head() %>%
gt(rowname_col = "name") %>%
tab_stubhead(label = "Car name")
tab_footnote()
.
Complexifier la structure avec des titres, des groupes de colonnes et de lignes
De manière similaire à la fonction add_header_above()
du package {kableExtra}
, il est possible de créer des groupes de colonnes, via la fonction tab_spanner()
:
head(iris) %>%
gt() %>%
tab_spanner(label = "Sepal", columns = c(1, 2)) %>%
tab_spanner(label = "Petal", columns = c(3, 4))
{kableExtra}
et sa fonction pack_rows()
, on peut ici créer des groupes de lignes, grâce à la fonction tab_row_group()
:
mtcars[1:10, 1:6] %>%
mutate(name = rownames(.)) %>%
gt(rowname_col = "name") %>%
tab_stubhead(label = "Car name") %>%
tab_row_group(group = "Group 2", rows = 8:10) %>%
tab_row_group(group = "Group 1", rows = 4:7) %>%
tab_row_group(group = " ", rows = 1:3)
Styliser sa table avec les couleurs et autres styles
C’est ici un peu plus complexe qu’avec le package {kableExtra}
: il faudra passer par la fonction tab_options()
et ses nombreux paramètres :
https://gt.rstudio.com/reference/tab_options.html
Par exemple : https://gist.github.com/rich-iannone/1da1ae7a7203958a0c5b1bd1d4b24017
Et ici, pour en savoir plus sur le package {gt}, avec des cas d’application plus poussés.
Le package {flextable} pour des tables dans Word et Powerpoint
Il vous sera utile pour générer des tables au format natif Microsoft Word / Powerpoint ou bien dans le cas où vous souhaitez générer votre document PDF via le package {pagedown}
.
Je vous laisse aller jeter un oeil à la page du package {flextable}
si vous souhaitez en savoir plus.
La suite…
Même si ces tables statiques sont préconisées pour les documents PDF ou Word, il est tout à fait possible de les intégrer dans une application Shiny ou un document HTML. Mais il existe un certain nombre de packages dédiés à la représentation de tables interactives, qui peuvent devenir un outil puissant de visualisation. La suite donc, au prochain numéro…