rgraph

Is there a way to make a flow map in R that ends with a value or a bar graph


I am trying to make something similar to a flow map to visualize outcomes based on a model I wrote. Given the dataframe I simulate below I'm looking for something similar to this image, ideally with bar graphs instead of the HD and MD values, but at this point I would just be happy with some values. Chart

Here is some code to generate the data frame I use:

library(Rmisc)
library(dplyr)

df <- data.frame(
  K = sample(c("Low", "High"), 100, replace = TRUE),
  A = sample(c("Low", "High"), 100, replace = TRUE),
  Q = sample(c("Low", "High"), 100, replace = TRUE),
  HD = runif(100, 0, 1),
  MD = runif(100, 0, 1)
)

df_long <- df %>%
pivot_longer(cols = c("HD", "MD"),
           names_to = "defense",
           values_to = "proportion")

fit <- summarySE(df_long,measurevar = "proportion",
             groupvars = c("defense","K","A","Q"))

I've tried using rpart and various other packages, but I can't seem to get anything like this.

Any help would be greatly appreciated.


Solution

  • I would approach this in three steps. First, produce your tree diagram:

    library(igraph)
    library(tidygraph)
    library(ggraph)
    library(patchwork)
    
    tree <- make_tree(15, 2) |>
      as_tbl_graph() |>
      mutate(num = 1:15) |>
      filter(num != 1) |>
      mutate(y = rep(seq(8, 1, length.out = 3), c(2, 4, 8))) |>
      mutate(x = c(3, 11, 1, 5, 9, 13, seq(0, 14, 2))) |>
      mutate(label = paste0("italic(", rep(c("K", "A", "Q"), c(2, 4, 8)))) |>
      mutate(label = paste0(label, c("[High])", "[Low])"))) |>
      ggraph(layout = "manual", x = x, y = y) +
      geom_edge_link() +
      geom_node_circle(aes(r = 0.6), fill = "white") +
      geom_node_text(aes(label = label), parse = TRUE, size = 5) +
      coord_equal(expand = FALSE, clip = "off") +
      theme_graph() +
      theme(plot.margin = margin(3, 3, 0, 3))
    

    Now produce your barplots:

    plots <- fit |>
      group_split(K, A, Q) |>
      lapply(function(d) {
        ggplot(d, aes(defense, proportion, fill = defense)) +
          geom_col(width = 0.5) +
          geom_text(aes(label = round(proportion, 2), y = 0.8)) +
          scale_fill_manual(values = c("navy", "red4"), guide = "none") +
          theme_void() +
          theme(axis.text.x = element_text()) +
          coord_cartesian(ylim = c(0, 1)) +
          scale_x_discrete(expand = c(1, 0.5))
      })
    

    Finally, join them together in patchwork:

    tree / 
      patchwork::wrap_plots(plots, ncol = 8) +
      plot_layout(heights = c(9, 2))
    

    enter image description here