Trouble with correct inputs for 100% stacked bars in plotly

Hello!

I posted this question over at SO and haven't gotten any responses so I figured I'd try here too. Edit: here's the link https://stackoverflow.com/questions/47537016/r-100-stacked-bars-in-plotly

I'm trying to create 100% stacked bars in plotly for a shiny app but am having some trouble with the inputs. The data are currently represented in a clustered vertical bar chart (code with sample data below), and I want the same data represented in a horizontal stacked bar, so one bar for Housed where Heterosexual, Gay or Lesbian, Bisexual, and Both add up to 100%, one bar for Homeless, 30 days where the same categories add up to 100%, etc. I thought it would be a simple switch but I'm struggling with the way the data are formatted and because the actual dataset is very large and I want to make many of these stacked bars for different indicators, the code before the plotly object needs to stay basically the same.

Also, based on another app I successfully did this in, I think I will need a different plotly object for each bar, is there a way around this or is this the best way?

Thanks for any help you can provide, and let me know if you have any questions or need clarification.

Thanks!

SexualOrientation<-c(1, 2, 1, 1, 1, 3, 4, 2, 1, 2, 2, 3, 4, 2, 2, 3, 3, 4, 4, 1, 1, 2)
q121<-c(1, 1, 1, 2, 3, 4, 1, 1, 1, 1, 2, 2, 2, 1, 2, 1, 1, 2, 1, 1, 1, 1)
q122<-c(2, 1, 1, 2, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 2, 1, 2, 2, 2)

d<-data.frame(SexualOrientation,q121,q122)

d$homeless <- ifelse(d$q121>1, 1, 0)
d$kickedout <- ifelse(d$q122==1, 1, 0)
d$homelessgroups[d$homeless==1 & d$kickedout==0] <- "Homeless, 30 days"
d$homelessgroups[d$homeless==0 & d$kickedout==1] <- "Homeless, Unaccompanied"
d$homelessgroups[d$homeless==1 & d$kickedout==1] <- "Both Homeless"
d$homelessgroups[d$homeless==0 & d$kickedout==0] <- "Housed"
d$homelessgroups <- ordered(d$homelessgroups, levels = c("Housed", "Homeless, 30 days", "Homeless, Unaccompanied", "Both Homeless"))
d$allhomeless <- ifelse(d$homelessgroups=="Housed", "Housed", "Homeless")


d$SexualOrientation[d$SexualOrientation==1] <- "Heterosexual"
d$SexualOrientation[d$SexualOrientation==2] <- "Gay or Lesbian"
d$SexualOrientation[d$SexualOrientation==3] <- "Bisexual"
d$SexualOrientation[d$SexualOrientation==4] <- "Not Sure"
d$SexualOrientation <- ordered(d$SexualOrientation, levels = c("Heterosexual", "Gay or Lesbian", "Bisexual", "Not Sure"))
SexualOrientation <- data.frame(d[, c(7, 1)])
SexualOrientation <- SexualOrientation[!is.na(SexualOrientation$allhomeless) & !is.na(SexualOrientation$SexualOrientation), ]
SOprop <- table(SexualOrientation$SexualOrientation, SexualOrientation$allhomeless)
SOdata <- melt(SOprop) 
SOtab <- dcast(melt(prop.table(table(SexualOrientation$SexualOrientation, SexualOrientation$allhomeless), 2)), Var1~Var2)
SOtab <- rename(SOtab, " " = Var1)
SOtab$Homeless <- percent(round(SOtab$Homeless, 3))
SOtab$Housed <- percent(round(SOtab$Housed, 3))
SOtab <- rbind(SOtab, pieSource)
SOHGroups <- data.frame(d[, c(6, 1)])
SOHGroups <- SOHGroups[!is.na(SOHGroups$homelessgroups) & !is.na(SOHGroups$SexualOrientation), ]
SOHGprop <- prop.table(table(SOHGroups$SexualOrientation, SOHGroups$homelessgroups), 2)
SOHGdata <- melt(SOHGprop)

plot_ly(data = SOHGdata[SOHGdata[, 2]=="Housed", ], x = ~Var1, y = ~value, type = "bar", name = "Housed", marker = list(color = "#32B6CD"),
    text = paste(percent(round(SOHGdata$value[SOHGdata[, 2]=="Housed"], 3))), hoverinfo = "name+text") %>%
  add_trace(data = SOHGdata[SOHGdata[, 2]=="Homeless, 30 days", ], y = ~value, name = "Homeless, <br>30 days", marker = list(color = "#FFE333"),
        text = paste(percent(round(SOHGdata$value[SOHGdata[, 2]=="Homeless, 30 days"], 3))), hoverinfo = "name+text") %>%
  add_trace(data = SOHGdata[SOHGdata[, 2]=="Homeless, Unaccompanied", ], y = ~value, name = "Homeless, <br>Unaccompanied", marker = list(color = "#FF9019"),
        text = paste(percent(round(SOHGdata$value[SOHGdata[, 2]=="Homeless, Unaccompanied"], 3))), hoverinfo = "name+text") %>%
  add_trace(data = SOHGdata[SOHGdata[, 2]=="Both Homeless", ], y = ~value, name = "Both <br>Homeless", marker = list(color = "#ed4f2e"),
        text = paste(percent(round(SOHGdata$value[SOHGdata[, 2]=="Both Homeless"], 3))), hoverinfo = "name+text") %>%
  layout(title = "Sexual Orientation", margin = list(t = 100, b = 100), xaxis = list(title = ""),
     yaxis = list(title = "Percent of Students", zeroline = FALSE, showline = FALSE, showticklabels = FALSE, showgrid = FALSE),
     barmode = "group", legend = list(x = .78, y = 1)) %>%
  add_annotations(text = "Source: Centers for Disease Control and Prevention",
              font = list(size = 10),
              align = "left",
              x = -0.05,
              y = -0.25,
              xref = "paper",
              yref = "paper",
              showarrow = FALSE)

You can put the link of your SO question. It could help follow if someone answer there and also will allow for someone who help you here, to help in SO too.

Thanks! I edited to include the link but here it is again https://stackoverflow.com/questions/47537016/r-100-stacked-bars-in-plotly.

This is a stacked bar chart of diamond clarity within cut -- it seems like you want something similar, but for sexual preference within housing type? https://plotly-book.cpsievert.me/bars-histograms.html#fig:cut-by-clarity-prop

1 Like