Les études cliniques commencent souvent par un tableau récapitulatif des caractéristiques démographiques des patients inclus dans l’étude afin de démontrer un équilibre entre les traitements et autres sous-groupes. Ce tableau se nomme “Demographic Tables”.
Le format est standard et peut être réalisé avec flextable en enchaînant 2 opérations.
Les deux étapes de la création de ces tableaux sont les suivantes :
flextable::summarizor()
. Elle calcule par groupes
et pour chaque variables un ensemble de statistiques. Elle retourne un data.frame prêt à être
consommé par flextable::as_flextable()
.as_flextable()
et le personnaliser
éventuellement avec les fonctions de ‘flextable’.library(flextable)
library(officer)
library(tidyverse)
library(safetyData)
use_df_printer()
set_flextable_defaults(
border.color = "#AAAAAA", font.family = "Arial",
font.size = 10, padding = 2, line_spacing = 1.5
)
adsl <- select(adam_adsl, AGE, SEX, BMIBLGR1, DURDIS, ARM)
adsl
AGE | SEX | BMIBLGR1 | DURDIS | ARM |
---|---|---|---|---|
numeric | character | character | numeric | character |
63 | F | 25-<30 | 43.9 | Placebo |
64 | M | >=30 | 76.4 | Placebo |
71 | M | >=30 | 42.8 | Xanomeline High Dose |
74 | M | 25-<30 | 55.3 | Xanomeline Low Dose |
77 | F | 25-<30 | 32.9 | Xanomeline High Dose |
85 | F | >=30 | 42.0 | Placebo |
68 | M | 25-<30 | 99.1 | Xanomeline Low Dose |
81 | F | <25 | 40.7 | Xanomeline Low Dose |
84 | M | <25 | 101.9 | Xanomeline Low Dose |
52 | M | <25 | 44.2 | Placebo |
n: 254 |
On va utiliser la fonction flextable::summarizor()
. Elle produit un
data.frame agrégé et structuré d’une façon idéale pour
un affichage avec flextable.
dat <- summarizor(adsl, by = "ARM")
dat
variable | stat | value1 | value2 | cts | percent | data_type | ARM |
---|---|---|---|---|---|---|---|
factor | factor | numeric | numeric | numeric | numeric | character | character |
AGE | mean_sd | 75.2 | 8.6 | continuous | Placebo | ||
AGE | median_iqr | 76.0 | 12.5 | continuous | Placebo | ||
AGE | range | 52.0 | 89.0 | continuous | Placebo | ||
AGE | missing | 0 | 0.0 | continuous | Placebo | ||
SEX | F | 53 | 0.6 | discrete | Placebo | ||
SEX | M | 33 | 0.4 | discrete | Placebo | ||
SEX | missing | 0 | 0.0 | discrete | Placebo | ||
BMIBLGR1 | <25 | 59 | 0.7 | discrete | Placebo | ||
BMIBLGR1 | >=30 | 6 | 0.1 | discrete | Placebo | ||
BMIBLGR1 | 25-<30 | 21 | 0.2 | discrete | Placebo | ||
n: 45 |
On souhaite un affichage où les traitements sont répartis en colonnes et où le contenu des paragraphes est assez souple pour permettre la création du tableau.
ft <- as_flextable(dat)
ft
Placebo | Xanomeline High Dose | Xanomeline Low Dose | |||||
---|---|---|---|---|---|---|---|
AGE | Mean (SD) | 75.2 (8.6) | 74.4 (7.9) | 75.7 (8.3) | |||
Median (IQR) | 76.0 (12.5) | 76.0 (9.2) | 77.5 (11.0) | ||||
Range | 52.0 - 89.0 | 56.0 - 88.0 | 51.0 - 88.0 | ||||
Missing | 0 (0.00%) | 0 (0.00%) | 0 (0.00%) | ||||
SEX | F | 53 (61.63%) | 40 (47.62%) | 50 (59.52%) | |||
M | 33 (38.37%) | 44 (52.38%) | 34 (40.48%) | ||||
Missing | 0 (0.00%) | 0 (0.00%) | 0 (0.00%) | ||||
BMIBLGR1 | <25 | 59 (68.60%) | 44 (52.38%) | 47 (55.95%) | |||
>=30 | 6 (6.98%) | 12 (14.29%) | 10 (11.90%) | ||||
25-<30 | 21 (24.42%) | 28 (33.33%) | 27 (32.14%) | ||||
Missing | 0 (0.00%) | 0 (0.00%) | 0 (0.00%) | ||||
DURDIS | Mean (SD) | 42.6 (30.2) | 40.5 (24.7) | 48.7 (29.6) | |||
Median (IQR) | 35.3 (25.8) | 36.0 (28.6) | 40.2 (39.9) | ||||
Range | 7.2 - 183.1 | 2.2 - 135.0 | 7.8 - 130.8 | ||||
Missing | 0 (0.00%) | 0 (0.00%) | 0 (0.00%) |
La méthode flextable::as_flextable()
supporte les arguments de la méthode
flextable::tabulator()
, on va utiliser l’argument spread_first_col = TRUE
pour répartir les noms des variables comme lignes de séparation et ne plus afficher
la colonne. On va aussi ajouter un caption et une note dans le bas du tableau et
quelques paramétrages supplémentaires.
ft <- as_flextable(dat, spread_first_col = TRUE, separate_with = "variable") %>%
bold(i = ~ !is.na(variable), j = 1, bold = TRUE) %>%
set_caption(
autonum = officer::run_autonum(seq_id = "tab", bkm = "demo_tab", bkm_all = FALSE),
fp_p = officer::fp_par(text.align = "left", padding = 5),
align_with_table = FALSE,
caption = as_paragraph(
"Demographic Characteristics",
"\nx.x: Study Subject Data"
)
) %>%
add_footer_lines("Source: ADaM adsl data frame from r package 'safetyData'") %>%
fix_border_issues() %>%
autofit()
ft
Placebo | Xanomeline High Dose | Xanomeline Low Dose | ||||
---|---|---|---|---|---|---|
AGE | ||||||
Mean (SD) | 75.2 (8.6) | 74.4 (7.9) | 75.7 (8.3) | |||
Median (IQR) | 76.0 (12.5) | 76.0 (9.2) | 77.5 (11.0) | |||
Range | 52.0 - 89.0 | 56.0 - 88.0 | 51.0 - 88.0 | |||
Missing | 0 (0.00%) | 0 (0.00%) | 0 (0.00%) | |||
SEX | ||||||
F | 53 (61.63%) | 40 (47.62%) | 50 (59.52%) | |||
M | 33 (38.37%) | 44 (52.38%) | 34 (40.48%) | |||
Missing | 0 (0.00%) | 0 (0.00%) | 0 (0.00%) | |||
BMIBLGR1 | ||||||
<25 | 59 (68.60%) | 44 (52.38%) | 47 (55.95%) | |||
>=30 | 6 (6.98%) | 12 (14.29%) | 10 (11.90%) | |||
25-<30 | 21 (24.42%) | 28 (33.33%) | 27 (32.14%) | |||
Missing | 0 (0.00%) | 0 (0.00%) | 0 (0.00%) | |||
DURDIS | ||||||
Mean (SD) | 42.6 (30.2) | 40.5 (24.7) | 48.7 (29.6) | |||
Median (IQR) | 35.3 (25.8) | 36.0 (28.6) | 40.2 (39.9) | |||
Range | 7.2 - 183.1 | 2.2 - 135.0 | 7.8 - 130.8 | |||
Missing | 0 (0.00%) | 0 (0.00%) | 0 (0.00%) | |||
Source: ADaM adsl data frame from r package 'safetyData' |
Cette partie va permettre de récupérer un ensemble de libellés que nous allons utiliser pour remplacer certains textes affichés dans le flextable.
La fonction à utiliser est labelizor()
, elle prend un simple argument
sous forme de vecteur nommé, les noms sont les valeurs à remplacer, les
valeurs sont les valeurs de remplacement.
On va récupérer les labels des colonnes stockées dans le tableau d’origine.
col_labels <- map_chr(adsl, function(x) attr(x, "label"))
col_labels
## AGE SEX
## "Age" "Sex"
## BMIBLGR1 DURDIS
## "Pooled Baseline BMI Group 1" "Duration of Disease (Months)"
## ARM
## "Description of Planned Arm"
ft <- labelizor(ft, j = "stat", labels = col_labels, part = "all")
ft
Placebo | Xanomeline High Dose | Xanomeline Low Dose | ||||
---|---|---|---|---|---|---|
Age | ||||||
Mean (SD) | 75.2 (8.6) | 74.4 (7.9) | 75.7 (8.3) | |||
Median (IQR) | 76.0 (12.5) | 76.0 (9.2) | 77.5 (11.0) | |||
Range | 52.0 - 89.0 | 56.0 - 88.0 | 51.0 - 88.0 | |||
Missing | 0 (0.00%) | 0 (0.00%) | 0 (0.00%) | |||
Sex | ||||||
F | 53 (61.63%) | 40 (47.62%) | 50 (59.52%) | |||
M | 33 (38.37%) | 44 (52.38%) | 34 (40.48%) | |||
Missing | 0 (0.00%) | 0 (0.00%) | 0 (0.00%) | |||
Pooled Baseline BMI Group 1 | ||||||
<25 | 59 (68.60%) | 44 (52.38%) | 47 (55.95%) | |||
>=30 | 6 (6.98%) | 12 (14.29%) | 10 (11.90%) | |||
25-<30 | 21 (24.42%) | 28 (33.33%) | 27 (32.14%) | |||
Missing | 0 (0.00%) | 0 (0.00%) | 0 (0.00%) | |||
Duration of Disease (Months) | ||||||
Mean (SD) | 42.6 (30.2) | 40.5 (24.7) | 48.7 (29.6) | |||
Median (IQR) | 35.3 (25.8) | 36.0 (28.6) | 40.2 (39.9) | |||
Range | 7.2 - 183.1 | 2.2 - 135.0 | 7.8 - 130.8 | |||
Missing | 0 (0.00%) | 0 (0.00%) | 0 (0.00%) | |||
Source: ADaM adsl data frame from r package 'safetyData' |
On va préparer le tableau pour un export dans Word en ajoutant une ligne d’entête comportant le numéro de page. Le caption va être auto-numéroté et aligné à gauche dans le document.
ft %>%
add_header_lines("Page ") %>%
append_chunks(i = 1, part = "header", j = 1, as_word_field(x = "Page")) %>%
save_as_docx(path = "adsl.docx")
Le document Word produit peut être téléchargé ici : adsl.docx. La miniature ci-dessous montre le document attendu.