0
votes

Is there a way to make a clustered stacked bar chart in R?

Currently I have 2 stacked bar charts that look like this:
(sorry for the links, I'm not yet able to post images to a question)
Stacked bar chart 1
Stacked bar chart 2

And my data looks something like this:

|state|A1|B1|C1|D1|E1|A2|B2|C2|D2  
|AL|  | 3| 2| 4|12| 2| 2| 8| 1| 6|
|AK|  | 2| 4|22| 6| 4| 4|12| 2| 3|
|AZ|  | 2| 1| 5| 5|45| 6| 2| 4|95|
|CA|  | 3| 9|11| 3|12| 7| 1| 5|25|

Using this data, is there a way to have a clustered stacked bar chart, so that the 2nd values are next to the 1st values for each state?

So far I've used plotly to make these graphs, and my code looks like this:

p1 <- plot_ly(data=df, x = ~state, y = ~E1, type = 'bar', name = 'E1') %>%
  add_trace(y = ~D1, name = 'D1') %>%
  add_trace(y = ~C1, name = 'C1') %>%
  add_trace(y = ~B1, name = 'B1') %>%
  add_trace(y = ~A1, name = 'A1') %>%
  layout(yaxis = list(title = ''), barmode = 'stack')
p1

Edit: I would want the final graph to look something like this: Chart Example
However for each state in the U.S

1
Can you post an example of the output you want from Excel?hmhensen
I added a chart example of what I would want my final product to look likeDasax121
So there are dates in your data? The sample data you provided have no date variables. You also say that you want "values" side by side but I'm not sure what those are in reference to in your sample data set.hmhensen

1 Answers

0
votes

You have two group variables ABCD and 1,2, so a longer data table might be better to work with ggplot2. For example, for each state, you have 4*2 = 8 "observations".

Here is the code to convert the dataframe into longer form with tidyr::pivot_longer and plot 2-group bar chart with ggplot2.

library(dplyr)
library(tidyr)
library(ggplot2)

df =data.table::fread(
"
|state|A1|B1|C1|D1|E1|A2|B2|C2|D2|
|AL   | 3| 2| 4|12| 2| 2| 8| 1| 6|
|AK   | 2| 4|22| 6| 4| 4|12| 2| 3|
|AZ   | 2| 1| 5| 5|45| 6| 2| 4|95|
|CA   | 3| 9|11| 3|12| 7| 1| 5|25|
"
)

df1 = df %>% 
  select(state, A1,B1,C1,D1,E1) %>% 
  pivot_longer(ends_with("1"))
df2 = df %>% 
  select(state, A2,B2,C2,D2) %>% 
  pivot_longer(ends_with("2")) 

dfall = rbind(df1,df2)%>% 
  mutate(group1= substr(name,1,1), # split "A1" to group1:"A" and group2:"1"
         group2= substr(name,2,2))

ggplot(dfall, aes(x=state,y = value, fill=group1, group=group2)) +
  geom_col(position = "dodge")

Created on 2019-12-20 by the reprex package (v0.3.0.9000)