Si vous vous intéressez de près ou de loin aux essais randomisés ou aux études observationnelles, vous avez très probablement rencontré des diagrammes Consort du flux des participants, notamment dans les publications. Il s’agit de diagrammes qui résument le flux des participants dans une étude. Comme ceci, par exemple :
D’après Billa, O., Bonnetain, F., Chamois, J., Ligey, A., Ganansia, V., Noel, G., … & Maingon, P. (2021). Randomized Trial Assessing the Impact of Routine Assessment of Health-Related Quality of Life in Patients with Head and Neck Cancer. Cancers, 13(15), 3826.
L’architecture de ces digrammes de flux de participants a été standardisée par la recommandation CONSORT (CONsolidated Standards Of Reporting Trials) dont le but est d’améliorer la rédaction et la transparence des essais randomisés contrôlés.
Voici le template disponible sur le site :
Et comme avec R on peut à peu près tout faire (ou presque !) , hé bien il existe un package pour réaliser ce type de diagramme : le package ggconsort développé par Travis Gerke.
Le principe de ce package est de réaliser automatiquement le diagramme à partir des données, en employant plusieurs étapes :
Alors honnêtement, on peut se demander quel est l’intérêt de réaliser un diagramme du flux des participants sous R alors qu’on peut le faire avec d’autres outils comme word, docs, powerpoint ou Slides, etc., c’est-à-dire avec des outils bien plus maniables.
À mon sens, il y a quelques avantages qui peuvent dépasser l’inconvénient majeur de maniabilité. Le premier c’est d’inscrire la réalisation du diagramme dans une démarche reproductible. Le second, c’est de limiter les erreurs puisque le diagramme est réalisé à partir des données. Le troisième, c’est d’automatiser la réalisation de ce graphique : le premier diagramme n’est pas facile à faire, mais une fois le template de code réalisé, il n’y a plus qu’à le réutiliser !
Je vous montre en pas à pas comment ça fonctionne !
Le package est à télécharger à partir d’un répertoire GitHub :
# install.packages("devtools")
devtools::install_github("tgerke/ggconsort")
library(ggconsort)
Un exemple de réalisation du digramme consort du flux des participants est également fourni sur le répertoire GitHub du package : https://github.com/tgerke/ggconsort.
L’exemple fourni s’appuie sur des données nommées trial_data
contenues dans le package :
head(trial_data)
## # A tibble: 6 x 5
## id declined prior_chemo bone_mets treatment
## <int> <int> <int> <int> <chr>
## 1 65464 0 0 0 Drug A
## 2 48228 0 0 0 Drug B
## 3 92586 0 0 0 Drug A
## 4 70176 0 0 0 Drug B
## 5 89052 0 0 0 Drug A
## 6 97333 0 0 0 Drug B
Remarque : Les données permettent uniquement de réaliser, le graphique ci-dessous, c’est-à-dire jusqu’à l’étape “Allocation”. Elles ne contiennent pas assez d’informations pour réaliser les étapes “Follow-up” et “Analysis”.
Les variables declined prior_chemo
, bone_mets
vont permettre de spécifier les groupes d’exclusion correspondants, et la variable treatment
va permettre de créer le groupe “Randomized” et les deux groupes de traitement.
Comme expliqué en introduction, la première étape consiste à définir les différents groupes de participants qui apparaissent dans le graphique. Pour cela, on emploie les fonctions cohort_start()
et cohort_define()
. La fonction cohort_start()
sert à initialiser en quelque sorte le groupe de départ (qui s’appelle alors .full), et c’est dans la fonction cohort_define()
que l’on définit les différents groupes.
Le code fourni en exemple m’a paru assez complexe, alors j’ai préféré le re-écrire comme cela :
library(dplyr)
study_cohorts <-
trial_data %>%
cohort_start("Assessed for eligibility") %>%
cohort_define(
randomized = .full %>% filter(!is.na(treatment)),
treatment_a = randomized %>% filter(treatment == "Drug A"),
treatment_b = randomized %>% filter(treatment == "Drug B"),
excluded = anti_join(.full, randomized, by = "id"),
excluded_declined = excluded %>% filter(declined==1),
excluded_chemo = excluded %>% filter(declined==0 & prior_chemo==1),
excluded_mets = excluded %>% filter(declined==0 & prior_chemo==0 & bone_mets==1))
Remarque : Pour ceux qui veulent comparer avec le code original, ce qui m’a embêté, c’est par exemple, que l’on définit un groupe “consented” dont on ne se sert pas directement dans le graph, mais que l’on utilise ensuite, uniquement pour filtrer l’ensemble du fichier ( excluded_declined = anti_join(.full, consented, by = "id")
).
On peut afficher les groupes créés comme cela :
summary(study_cohorts)
## # A tibble: 8 x 3
## cohort count label
## <chr> <int> <chr>
## 1 .full 1200 Assessed for eligibility
## 2 randomized 938 <NA>
## 3 treatment_a 469 <NA>
## 4 treatment_b 469 <NA>
## 5 excluded 262 <NA>
## 6 excluded_declined 59 <NA>
## 7 excluded_chemo 113 <NA>
## 8 excluded_mets 90 <NA>
Nous pouvons ensuite appliquer des étiquettes aux différents groupes :
study_cohorts <- study_cohorts %>%
cohort_label(
randomized = "Randomized",
treatment_a = "Allocated to arm A",
treatment_b = "Allocated to arm B",
excluded = "Excluded",
excluded_declined = "Declined to participate",
excluded_chemo = "Prior chemotherapy",
excluded_mets = "Bone metastasis"
)
summary(study_cohorts)
## # A tibble: 8 x 3
## cohort count label
## <chr> <int> <chr>
## 1 .full 1200 Assessed for eligibility
## 2 randomized 938 Randomized
## 3 treatment_a 469 Allocated to arm A
## 4 treatment_b 469 Allocated to arm B
## 5 excluded 262 Excluded
## 6 excluded_declined 59 Declined to participate
## 7 excluded_chemo 113 Prior chemotherapy
## 8 excluded_mets 90 Bone metastasis
Voici l’ensemble du code :
study_consort <- study_cohorts %>%
consort_box_add(
"full", 0, 50, cohort_count_adorn(study_cohorts, .full)
) %>%
consort_box_add(
"exclusions", 20, 40, glue::glue(
'{cohort_count_adorn(study_cohorts, excluded)}<br>
• {cohort_count_adorn(study_cohorts, excluded_declined)}<br>
• {cohort_count_adorn(study_cohorts, excluded_chemo)}<br>
• {cohort_count_adorn(study_cohorts, excluded_mets)}
')
) %>%
consort_box_add(
"randomized", 0, 30, cohort_count_adorn(study_cohorts, randomized)
) %>%
consort_box_add(
"arm_a", -30, 10, cohort_count_adorn(study_cohorts, treatment_a)
) %>%
consort_box_add(
"arm_b", 30, 10, cohort_count_adorn(study_cohorts, treatment_b)
) %>%
consort_arrow_add(
end = "exclusions", end_side = "left", start_x = 0, start_y = 40
) %>%
consort_arrow_add(
"full", "bottom", "randomized", "top"
) %>%
consort_arrow_add(
start_x = 0, start_y = 30, end_x = 0, end_y = 20,
) %>%
consort_line_add(
start_x = -30, start_y = 20, end_x = 30, end_y = 20,
) %>%
consort_arrow_add(
end = "arm_a", end_side = "top", start_x = -30, start_y = 20
) %>%
consort_arrow_add(
end = "arm_b", end_side = "top", start_x = 30, start_y = 20
)
Les boites sont créées par la fonction consort_box_add()
et sont stockées dans l’objet graphique study_consort
:
Les flèches sont créés par la foncion consort_arrow_add(), les lignes sont créés par la foncion consort_line_add() et sont stockées dans l’objet graphique study_consort :
Une fois le digramme construit, il reste à le réaliser avec ggplot2
, en employant la géométrie geom_consort() :
library(ggplot2)
study_consort %>%
ggplot() +
geom_consort() +
theme_consort(margin_h = 8, margin_v = 1) +
# you can include other ggplot geoms, as needed -------------
ggtext::geom_richtext(
aes(x = 0, y = 10, label = "Allocation"),
fill = "#9bc0fc"
)
Pour créer les étapes “follow-up” et “analysis”, il est nécessaire de suivre les mêmes étapes :
ggtext::geom_richtext()
Pour créer les groupes, vos données doivent contenir les informations correspondantes, c’est-à-dire, au moins une variable complete_follow_up
(codée en 0/1), voir des variables détaillant le suivi comme died
codée (0/1), et lost
(codée en 0/1), par exemple.
J’espère que cet article vous aura permis, à minima de découvrir les diagrammes de participants et la recommandation CONSORT. Et pour certaines et certains d’entre vous, qu’il vous permettra de vous lancer plus facilement dans la réalisation automatisée et reproductible de ces diagrammes avec R.
💡 ❓❓ Est ce que cela vous intéresse que je crée un template pour réaliser un digramme consort du flux des participants complet, c’est-à-dire avec les étapes Follow-Up et Analysis . ❓❓
🙏 Dites le moi en commentaire, ou envoyez-moi un mail : claire@delladata.fr
Si cet article vous a plu, ou vous a été utile, et si vous le souhaitez, vous pouvez soutenir ce blog en faisant un don sur sa page Tipeee.
Enregistrez vous pour recevoir gratuitement mes fiches “aide mémoire” (ou cheat sheets) qui vous permettront de réaliser facilement les principales analyses biostatistiques avec le logiciel R et pour être informés des mises à jour du site.
Une réponse
Merci pour cette présentation, fort utile pour mes publications !