rdataframeggplot2stacked-chartstacked

R code - help creating a 100% stacked bar chart like the below image with ggplot:


I have the below dataframe reproducible code:

dput(u) <-
structure(list(name = c("rankings_message_1", "rankings_message_2", 
"rankings_message_3", "rankings_message_4", "rankings_message_5", 
"rankings_message_6", "rankings_message_7", "rankings_message_8", 
"rankings_message_9", "rankings_message_10", "rankings_message_11", 
"rankings_message_12", "rankings_message_13", "rankings_message_1", 
"rankings_message_2", "rankings_message_3", "rankings_message_4", 
"rankings_message_5", "rankings_message_6", "rankings_message_7", 
"rankings_message_8", "rankings_message_9", "rankings_message_10", 
"rankings_message_11", "rankings_message_12", "rankings_message_13", 
"rankings_message_1", "rankings_message_2", "rankings_message_3", 
"rankings_message_4", "rankings_message_5", "rankings_message_6", 
"rankings_message_7", "rankings_message_8", "rankings_message_9", 
"rankings_message_10", "rankings_message_11", "rankings_message_12", 
"rankings_message_13", "rankings_message_1", "rankings_message_2", 
"rankings_message_3", "rankings_message_4", "rankings_message_5", 
"rankings_message_6", "rankings_message_7", "rankings_message_8", 
"rankings_message_9", "rankings_message_10", "rankings_message_11", 
"rankings_message_12", "rankings_message_13", "rankings_message_1", 
"rankings_message_2", "rankings_message_3", "rankings_message_4", 
"rankings_message_5", "rankings_message_6", "rankings_message_7", 
"rankings_message_8", "rankings_message_9", "rankings_message_10", 
"rankings_message_11", "rankings_message_12", "rankings_message_13", 
"rankings_message_1", "rankings_message_2", "rankings_message_3", 
"rankings_message_4", "rankings_message_5", "rankings_message_6", 
"rankings_message_7", "rankings_message_8", "rankings_message_9", 
"rankings_message_10", "rankings_message_11", "rankings_message_12", 
"rankings_message_13", "rankings_message_1", "rankings_message_2", 
"rankings_message_3", "rankings_message_4", "rankings_message_5", 
"rankings_message_6", "rankings_message_7", "rankings_message_8", 
"rankings_message_9", "rankings_message_10", "rankings_message_11", 
"rankings_message_12", "rankings_message_13", "rankings_message_1", 
"rankings_message_2", "rankings_message_3", "rankings_message_4", 
"rankings_message_5", "rankings_message_6", "rankings_message_7", 
"rankings_message_8", "rankings_message_9", "rankings_message_10", 
"rankings_message_11", "rankings_message_12", "rankings_message_13", 
"rankings_message_1", "rankings_message_2", "rankings_message_3", 
"rankings_message_4", "rankings_message_5", "rankings_message_6", 
"rankings_message_7", "rankings_message_8", "rankings_message_9", 
"rankings_message_10", "rankings_message_11", "rankings_message_12", 
"rankings_message_13", "rankings_message_1", "rankings_message_2", 
"rankings_message_3", "rankings_message_4", "rankings_message_5", 
"rankings_message_6", "rankings_message_7", "rankings_message_8", 
"rankings_message_9", "rankings_message_10", "rankings_message_11", 
"rankings_message_12", "rankings_message_13", "rankings_message_1", 
"rankings_message_2", "rankings_message_3", "rankings_message_4", 
"rankings_message_5", "rankings_message_6", "rankings_message_7", 
"rankings_message_8", "rankings_message_9", "rankings_message_10", 
"rankings_message_11", "rankings_message_12", "rankings_message_13", 
"rankings_message_1", "rankings_message_2", "rankings_message_3", 
"rankings_message_4", "rankings_message_5", "rankings_message_6", 
"rankings_message_7", "rankings_message_8", "rankings_message_9", 
"rankings_message_10", "rankings_message_11", "rankings_message_12", 
"rankings_message_13", "rankings_message_1", "rankings_message_2", 
"rankings_message_3", "rankings_message_4", "rankings_message_5", 
"rankings_message_6", "rankings_message_7", "rankings_message_8", 
"rankings_message_9", "rankings_message_10", "rankings_message_11", 
"rankings_message_12", "rankings_message_13"), value = c(5, 6, 
3, 13, 10, 12, 7, 19, 3, 7, 3, 5, 6, 6, 3, 6, 13, 7, 15, 9, 11, 
7, 6, 6, 4, 8, 7, 8, 4, 11, 6, 11, 11, 11, 6, 6, 5, 8, 6, 8, 
7, 6, 9, 6, 11, 9, 7, 9, 7, 7, 7, 6, 8, 6, 8, 7, 9, 7, 7, 10, 
9, 6, 7, 9, 7, 7, 11, 7, 7, 8, 7, 6, 7, 9, 10, 7, 8, 7, 8, 7, 
11, 5, 6, 4, 7, 4, 11, 9, 6, 10, 11, 9, 8, 9, 5, 7, 6, 6, 6, 
8, 9, 9, 8, 10, 9, 9, 9, 5, 5, 4, 7, 6, 9, 11, 10, 9, 8, 10, 
7, 10, 6, 4, 6, 7, 5, 7, 8, 8, 10, 10, 8, 7, 8, 7, 6, 7, 7, 4, 
9, 8, 11, 8, 9, 9, 8, 9, 9, 7, 4, 7, 5, 8, 9, 10, 7, 6, 5, 13, 
10, 4, 18, 5, 11, 4, 4, 5, 9, 6, 5)), row.names = c(NA, -169L
), class = c("tbl_df", "tbl", "data.frame"))

And this is my ggplot code:

ggplot(u, aes(value, factor(value), fill = name)) +
  geom_bar(stat = "identity", position = "fill")+ # #position fill makes them all 100%
  geom_text(aes(label=value), position = position_stack(vjust = .5), color = "White", size =7)

which makes this chart:

![enter image description here][1]

But I want to create something like this: deleted

Ive tried different combinations inside ggplot but cant seem to get it to show right. I believe I need to use the factor functior in there somewhere but could be mistaken.... Overall, each bar is a "message" and each message/bar is broken down into 13 chunks which are %'s. I want each % chunck to be a different color as shown in the image I am trying to create. Any help would be appreciated!


Solution

  • Your data contains the y axis variable ("name") and the x axis variable ("value"), but does not contain a grouping variable by which to stack or color-fill the bars (the original has a variable called "rank" which you don't have).

    You can make an equivalent variable by grouping by the "name" variable and creating a sequence along the group which you then convert to a factor. You need to use position = "fill" on the text as well as the bars.

    library(tidyverse)
    
    u %>%
      group_by(name) %>%
      mutate(element = factor(row_number(name))) %>%
      ggplot(aes(value, name, fill = element)) +
      geom_col(position = "fill") +
      geom_text(aes(label=value), position = position_fill(vjust = .5), 
                color = "White", size = 7) +
      scale_fill_discrete(guide = "none")
    

    enter image description here

    Or, to get it to look more like the original, use facets, a dummy y variable, an appropriate color palette and some theme changes:

    u %>%
      group_by(name) %>%
      mutate(element = factor(row_number(name)),
             name = factor(name,
                           paste("rankings_message", 13:1, sep = "_"))) %>%
      
      ggplot(aes(value, "1", fill = element)) +
      geom_col(position = "fill", orientation = "y", size = 0.5, col = "white") +
      geom_text(aes(label=value), position = position_fill(vjust = .5), 
                color = "White", size = 7) +
      scale_fill_manual(guide = "none",
                        values = rev(c("#ffb04d", "#ff8a1e", "#e5573e", "#af0020",
                                       "#3e84ac", "#64baff", "#96a7dd", "#765ab1", 
                                       "#483374", "#ce74a5", "#ffb04d", "#ff8a1e",
                                       "#e3583f"))) +
      facet_wrap(vars(name), nrow = 13) +
      theme_void() +
      theme(strip.text = element_text(hjust = 0.05))
    

    enter image description here