Using Gmisc/Glue/Grid

Code
library(Gmisc)
library(glue)
library(grid)
library(tidyverse)

font.cex <- .6
total_population = 1000
reason_excluded_1 = 10
reason_excluded_2 = 2
total_excluded = reason_excluded_1 + reason_excluded_2
eligible = total_population - total_excluded
reason_excluded_3 = 20
included_in_final_analysis = eligible - reason_excluded_3
derivation_cohort = 668
validation_cohort = included_in_final_analysis - 668



org_cohort <- boxGrob(
  txt_gp = gpar(col = "black", cex = font.cex),
  glue("Kidney transplant recipients",
    "n = {total_population}",
    pop = txtInt(1000),
    .sep = "\n"
  )
)


excluded1 <- boxGrob(
  txt_gp = gpar(col = "black", cex = font.cex),
  glue(
    
    "Excluded (n = {total_excluded}):",
    " - reason 1 (n = {reason_excluded_1})",
    " - reason 2 (n = {reason_excluded_2})",
    ,
    .sep = "\n"
  ),
  just = "left"
)


eligible <- boxGrob(
  txt_gp = gpar(col = "black", cex = font.cex),
  glue(
    "Kidney transplant recipients 
    with only one transplant",
    "n = {eligible}",
    .sep = "\n"
  )
)


excluded2 <- boxGrob(
  txt_gp = gpar(col = "black", cex = font.cex),
  glue("Excluded reason 3 (n = {reason_excluded_3}):",
    .sep = "\n"
  ),
  just = "left"
)


included <- boxGrob(
  txt_gp = gpar(col = "black", cex = font.cex),
  glue(
    "Kidney transplant recipients
    included in the final analyses",
    "n = {included_in_final_analysis}",
    .sep = "\n"
  )
)


grp_a <- boxGrob(
  txt_gp = gpar(col = "black", cex = font.cex),
  glue("Derivation cohort
(Australia)",
    "n = {derivation_cohort}",
    .sep = "\n"
  )
)



grp_b <- boxGrob(
  txt_gp = gpar(col = "black", cex = font.cex),
  glue("Validation cohort
(New Zealand)",
    "n = {validation_cohort}",
    .sep = "\n"
  )
)


grid.newpage()

vert <- spreadVertical(
  org = org_cohort,
  eligible = eligible,
  included = included,
  grps = grp_a
)

grps <- alignVertical(
  reference = vert$grps,
  grp_a, grp_b
) %>%
  spreadHorizontal()

vert$grps <- NULL



excluded1 <- moveBox(excluded1,
  x = .8,
  y = coords(vert$org)$bottom -

    distance(vert$eligible, vert$org,
      half = TRUE, center = FALSE
    )
)



excluded2 <- moveBox(excluded2,
  x = .8,
  y = coords(vert$eligible)$bottom -

    distance(vert$included, vert$eligible,
      half = TRUE, center = FALSE
    )
)


for (i in 1:(length(vert) - 1)) {
  connectGrob(vert[[i]], vert[[i + 1]],
    type = "vert",
    arrow_obj = arrow(
      angle = 30,
      length = unit(0.1, "inches"),
      ends = "last", type = "closed"
    )
  ) %>%
    print()
}

connectGrob(vert$included, grps[[1]],
  type = "N",
  arrow_obj = arrow(
    angle = 30,
    length = unit(0.1, "inches"),
    ends = "last", type = "closed"
  )
)

connectGrob(vert$included, grps[[2]],
  type = "N",
  arrow_obj = arrow(
    angle = 30,
    length = unit(0.1, "inches"),
    ends = "last", type = "closed"
  )
)



connectGrob(vert$eligible, excluded1,
  type = "L",
  arrow_obj = arrow(
    angle = 30,
    length = unit(0.1, "inches"),
    ends = "last", type = "closed"
  )
)

connectGrob(vert$included, excluded2,
  type = "L",
  arrow_obj = arrow(
    angle = 30,
    length = unit(0.1, "inches"),
    ends = "last", type = "closed"
  )
)





# Print flux

vert
grps
excluded1
excluded2

Using mermaid

Code
flowchart TD

  A[Total population] -- Excluded for some reason --> B(Eligible)
  B -- Excluded for another reason --> C(Patients included in final analysis)
  C --> D[Derivation cohort]
  C --> E[Validation cohort]
flowchart TD

  A[Total population] -- Excluded for some reason --> B(Eligible)
  B -- Excluded for another reason --> C(Patients included in final analysis)
  C --> D[Derivation cohort]
  C --> E[Validation cohort]