Example 1
In this example, we will try to create a flowchart for the complete flow of patients in the SAFO study:
safo |>
as_fc(label = "Patients assessed for eligibility") |>
fc_filter(!is.na(group), label = "Randomized", show_exc = TRUE) |>
fc_split(group) |>
fc_filter(itt == "Yes", label = "Included in ITT") |>
fc_filter(pp == "Yes", label = "Included in PP") |>
fc_draw()
Example 2
In this example, we will try to exactly reproduce the original flowchart of the SAFO study published in Nature Medicine: SAFO flowchart.
First, we need to do some pre-processing to reproduce the text in the larger boxes:
# Create labels for exclusion box:
label_exc <- paste(
c(str_glue("{sum(safo$inclusion_crit == 'Yes' | safo$exclusion_crit == 'Yes' | safo$decline_part == 'Yes', na.rm = T)} excluded:"),
map_chr(c("inclusion_crit", "decline_part", "exclusion_crit"), ~str_glue("{sum(safo[[.x]] == 'Yes', na.rm = TRUE)} {attr(safo[[.x]], 'label')}")),
map_chr(4:15, ~str_glue(" - {sum(safo[[.x]] == 'Yes')} {attr(safo[[.x]], 'label')}"))),
collapse = "\n")
label_exc <- gsub("exclusion criteria", "exclusion criteria:", label_exc)
safo1 <- safo |>
filter(group == "cloxacillin plus fosfomycin", !is.na(reason_pp)) |>
mutate(reason_pp = droplevels(reason_pp))
label_exc1 <- paste(
c(str_glue("{nrow(safo1)} excluded:"),
map_chr(levels(safo1$reason_pp), ~str_glue(" - {sum(safo1$reason_pp == .x)} {.x}"))),
collapse = "\n")
label_exc1 <- str_replace_all(label_exc1, c("nosocomial" = "nosocomial\n", "treatment" = "treatment\n"))
safo2 <- safo |>
filter(group == "cloxacillin alone", !is.na(reason_pp)) |>
mutate(reason_pp = droplevels(reason_pp))
label_exc2 <- paste(
c(str_glue("{nrow(safo2)} excluded:"),
map_chr(levels(safo2$reason_pp), ~str_glue(" - {sum(safo2$reason_pp == .x)} {.x}"))),
collapse = "\n")
label_exc2 <- str_replace_all(label_exc2, c("resistant" = "resistant\n", "blood" = "blood\n"))
Second, let’s create and customize the flowchart using the functions in the package:
safo |>
as_fc(label = "patients assessed for eligibility", text_pattern = "{N} {label}") |>
fc_filter(!is.na(group), label = "randomized", text_pattern = "{n} {label}", show_exc = TRUE, just_exc = "left", text_pattern_exc = "{label}", label_exc = label_exc, text_fs_exc = 7, offset_exc = 0.15) |>
fc_split(group, text_pattern = "{n} asssigned\n {label}") |>
fc_filter(itt == "Yes", label = "included in intention-to-treat\n population", show_exc = TRUE, text_pattern = "{n} {label}", label_exc = "patient did not receive allocated\n treatment (withdrew consent)", text_pattern_exc = "{n} {label}", text_fs_exc = 7) |>
fc_filter(pp == "Yes", label = "included in per-protocol\n population", show_exc = TRUE, just_exc = "left", text_pattern = "{n} {label}", text_fs_exc = 7) |>
fc_modify(
~.x |>
filter(n != 0) |>
mutate(
text = case_when(id == 11 ~ label_exc1, id == 13 ~ label_exc2, TRUE ~ text)
)
) |>
fc_draw()
Example 3
In this example, we will create a flowchart without any
data.frame
, using the N
argument to manually
specify the numbers to display in the boxes:
as_fc(N = 300) |>
fc_filter(N = 240, label = "Randomized patients", show_exc = TRUE) |>
fc_split(N = c(100, 80, 60), label = c("Group A", "Group B", "Group C")) |>
fc_filter(N = c(80, 75, 50), label = "Finished the study") |>
fc_draw()
Example 4
The use of N=
argument can be combined with the use of a
data.frame
. In this example, we will use the
N=
argument in a flowchart that uses a
data.frame
:
safo |>
as_fc(label = "Patients assessed for eligibility") |>
fc_filter(!is.na(group), label = "Randomized", show_exc = TRUE) |>
fc_split(group) |>
fc_split(N = c(50, 55, 10, 100), label = c("Group A", "Group B")) |>
fc_draw()
Example 5
In this example, we will attempt to recreate the flowchart suggested by the CONSORT guideline:
as_fc(N = 200, label = "Assessed for eligibility", title = "Enrollment") |>
fc_filter(N = 150, label = "Randomized", show_exc = TRUE, just_exc = "left") |>
fc_split(N = c(70, 80), label = c("Allocated to control", "Allocated to intervention"), title = "Allocation", x_title = 0.5) |>
fc_filter(N = c(50, 65), label = "Completed follow-up", title = "Follow-Up", just = "left", x_title = 0.5) |>
fc_filter(N = c(48, 63), label = "Analysed", title = "Analysis", just = "left", x_title = 0.5) |>
fc_theme(text_pattern = "{label} (n = {n})", text_pattern_init = "{label} (n = {n})", text_pattern_exc = "{label} (n = {n}):") |>
fc_modify(
~ . |>
mutate(
text = case_when(
id == 4 ~ paste0(text, "\n - Not meeting inclusion criteria (n = 20)\n - Declined to participate (n = 25)\n - Other reasons (n = 5)"),
id == 8 ~ paste0(text, "\nLost to follow-up (n = 15):\n -Could not be contacted (n = 10)\n -Died from other causes (n = 5)\nDiscontinued intervention (n = 5):\n -Adverse events from intervention (n = 4)\n -Protocol violation (n = 1)"),
id == 9 ~ paste0(text, "\nLost to follow-up (n = 18):\n -Could not be contacted (n = 13)\n -Died from other causes (n = 5)\nDiscontinued intervention (n = 7):\n -Adverse events from intervention (n = 3)\n -Protocol violation (n = 4)"),
id == 11 ~ paste0(text, "\nExcluded from analysis (n = 2):\n -Missing primary outcome (n = 2)"),
id == 12 ~ paste0(text, "\nExcluded from analysis (n = 2):\n -Missing primary outcome (n = 2)"),
.default = text
)
)
) |>
fc_draw()