Search code examples
rflowchart

Flow chart using R


I've been struggling the whole day with creating a flow chart to represent some patients we included in a study.

I already have a rough version ready in a Power Point presentation, depicting what kind of arrangement I'm looking for.

Structure I'm trying to recreate

Now, I've got all my boxes ready, but what I need is the same alignment and connection to the arrows as in the picture attached. I have tried to somewhat copy and paste the guide on this page https://cran.r-project.org/web/packages/Gmisc/vignettes/Grid-based_flowcharts.html, but now I'm stuck. Since I have little expertise using R and only work with it occasionally, there might be something easy you might see, that I don't.

Here's my code:

  install.packages("Gmisc")
library(Gmisc, quietly = TRUE)
library(glue)
library(htmlTable)
library(grid)
library(magrittr)

org_cohort <- boxGrob(glue("Patients with pancreatic cancer admitted to the University Clinic of Essen",
                           "from 01/2002 to 08/2020",
                           "n = {pop}",
                           pop = txtInt(909),
                           .sep = "\n"))
included <- boxGrob(glue("Patients with genetic sequencing and survival data",
                         "n = {incl}",
                         incl = txtInt(412),
                         .sep = "\n"))
grp_a <- boxGrob(glue("Patients treated with FOLFIRINOX or Gemcitabine / nab-Paclitaxel",
                      "n = {recr}",
                      recr = txtInt(179),
                      .sep = "\n"))

grp_b <- boxGrob(glue("Patients with genetic sequencing data via MAPK-TRON panel",
                      "n = {recr}",
                      recr = txtInt(185),
                      .sep = "\n"))

excluded_1 <- boxGrob(glue("Excluded (n = {tot}):",
                         " - No survival data: {NoSurv}",
                         " - No MAPK-Tron panel and early available abdominal CT-scan: {NoMAPKCT}",
                         tot = 506,
                         NoSurv = 300,
                         NoMAPKCT = 206,
                         .sep = "\n"),
                    just = "left")

excluded_2 <- boxGrob(glue("Excluded (n = {NoFGP}):",
                           " - No FOLFIRINOX or Gemcitabine / nab-Paclitaxel as 1st line: {NoFGP}",
                           NoFGP = 233,
                           .sep = "\n"),
                      just = "left")

excluded_3 <- boxGrob(glue("Excluded (n = {NoMAPK}):",
                           " - No sequencing data available: {NoMAPK}",
                           NoMAPK = 227,
                           .sep = "\n"),
                      just = "left")

grid.newpage()
vert <- spreadVertical(org_cohort = org_cohort,
                       included = included,
                       grps = grp_a)
grps <- alignVertical(reference = vert$grp_a,
                      grp_a, grp_b) %>%
  spreadHorizontal()
vert$grps <- NULL

excluded_1 <- moveBox(excluded_1,
                    x = .8,
                    y = coords(vert$included)$top + distance(vert$included, vert$org_cohort, half = TRUE, center = FALSE))

excluded_2 <- moveBox(excluded_2,
                      x = .8,
                      y = coords(vert$grp_a)$top + distance(vert$included, vert$grp_a, half = TRUE, center = FALSE))

excluded_3 <- moveBox(excluded_3,
                      x = .8,
                      y = coords(vert$grp_b)$bottom + distance(vert$included, vert$grp_b, half = TRUE, center = FALSE))

## already facing problems here: R gives me the following error message: Error in coords(vert$grp_a/b) : 
  #Assertion on 'box' failed: Must inherit from class 'box', but has class 'NULL'..

for (i in 1:(length(vert) - 1)) {
  connectGrob(vert[[i]], vert[[i + 1]], type = "vert") %>%
    print
}
connectGrob(vert$included, grps[[1]], type = "N")
connectGrob(vert$included, grps[[2]], type = "N")

connectGrob(vert$included, excluded_1, type = "L")
connectGrob(vert$grp_a, excluded_2, type = "L")



# Print boxes
vert
grps
excluded_1
excluded_2
excluded_3

I'll be honest: I don't really get the code after the "grid.newpage()" thing. Therefore I'm constantly trying something to understand what the components of the code actually do, but every time I think I understood how it works, another setback is waiting for me around the corner. R basically gives me a plot with arrows and boxes all over the place, but not the way I want them to look like. Then sometimes my boxes are even too large or something? Especially the boxes of the two subgroups at the end of the chart are cut-off oftentimes...

Do you have an idea how to "force" R replicating that kind of chart (see picture) for me?

Your help is extremely appreciated and would bring me a step closer to finally finish my thesis...!

Thank you in advance!!


Solution

  • Here is something to get your started with DiagrammeR.

    • Use splines = ortho to get 90 degree angles and straight lines.
    • Add line breaks with <br/> in the labels of nodes.
    • Use blank nodes to get branches for exclusion boxes. Then use rank to get the hidden blank nodes to line up with exclusion boxes.

    Hope this is helpful.

    library(DiagrammeR)
    
    grViz(
         "digraph my_flowchart { 
          graph[splines = ortho]
          node [fontname = Helvetica, shape = box, width = 4, height = 1]
          
            node1[label = <Pancreatic cancer patients treated at our center<br/>diagnosed 2002-2020<br/>(n = 909)>]
            node2[label = <Patients with MAPK-TRON panel and/or<br/>early available abdominal CT scan (n = 412)>]
            
            blank1[label = '', width = 0.01, height = 0.01]
            excluded1[label = <Exclusion of patients without<br/>(1) MARK-TRON panel and early available abdominal CT scan, and<br/>(2) survival data<br/>(n = 506)>]
            
            node1 -> blank1[dir = none];
            blank1 -> excluded1[minlen = 2];
            blank1 -> node2;
            { rank = same; blank1 excluded1 }
            
            node3[label = <FOLFIRINOX or Gemcitabine/nab-Paclitaxel as first CTx<br/>(n = 179)>]
            node4[label = <Patients with MAPK-TRON panel regardless of CT scans<br/>(n = 185)>]
            
            blank2[label = '', width = 0.01, height = 0.01]
            excluded2[label = <Exclusion of patients that did not receive<br/>FOLFIRINOX or Gemcitabine/nab Paclitaxel as first CTx<br/>(n = 233)>]
            
            blank3[label = '', width = 0.01, height = 0.01]
            excluded3[label = <Exclusion of patients without MAPK-TRON panel<br/>(n = 227)>]
            
            node2 -> blank2[dir = none];
            node2 -> blank3[dir = none];
            
            blank2 -> excluded2[minlen = 2];
            blank3 -> excluded3[minlen = 2];
            
            blank2 -> node3;
            blank3 -> node4;
            
            { rank = same; blank2 excluded2 blank3 excluded3 }
         }"
    )
    

    Diagram

    diagrammer image