I'm trying to sort a stacked barchart object created by ggplot by having the item with the highest "Excellent" value first. My current code doesn't seem to sort it that way:
R_POPS_testdataset_forstackedbars <- read_csv("R-POPS testdataset forstackedbars.csv") # dataset for testing purposes
RPOPS_ggchart01 <- ggplot(R_POPS_testdataset_forstackedbars, aes(x = Variable_name, y = Rating_prop, fill = factor(Rating, levels=c("Poor","Fair","Good","Very Good","Excellent"))))
geom_bar(stat="identity", position ="fill", width=0.8) coord_flip() scale_fill_manual("legend", values = c("Excellent" = "#275E6B", "Very Good" = "#4AAAC4", "Good" = "#8CD4E5", "Fair" = "#F7963D", "Poor" = "#BE2327")) # color scheme for stacked bars
RPOPS_ggchart01 <- RPOPS_ggchart01 geom_text(aes(label=paste0(sprintf("%1.f", Rating_prop*100),"%")),
position=position_fill(vjust=0.5), color="white", size=9)
My data is structured like this:
structure(list(Rating = c("Excellent", "Fair", "Good", "Poor",
"Very Good", "Excellent", "Fair", "Good", "Poor", "Very Good"
), Variable_name = c("Overall effectiveness of adminstrative support for the program",
"Overall effectiveness of adminstrative support for the program",
"Overall effectiveness of adminstrative support for the program",
"Overall effectiveness of adminstrative support for the program",
"Overall effectiveness of adminstrative support for the program",
"Overall effectiveness of your Program Director", "Overall effectiveness of your Program Director",
"Overall effectiveness of your Program Director", "Overall effectiveness of your Program Director",
"Overall effectiveness of your Program Director"), Rating_prop = c(0.13,
0.35, 0.17, 0.13, 0.22, 0.39, 0.09, 0.26, 0.09, 0.17)), row.names = c(NA,
-10L), class = c("tbl_df", "tbl", "data.frame"))
CodePudding user response:
To answer your question and check the answer I had to expand your initial dataset, but it should work with no problem with your original data.
I've used reorder ave to reorder the bars. Basically, with ave you want to associate the value of Excellent to each value of Variable_name (even when Rating isn't Excellent). So that reorder knows that the same Variable_name value should be treated equally. replace is necessary in case you have no Excellent value: it just replaces the NA you would have with a zero. Note that I had to setNames, that's because I had to select the Rating_prop associated with the Rating Excellent.
# data
set.seed(1)
df <- data.frame(Variable_name = rep(LETTERS[1:5], each = 5),
Rating = c("Poor","Fair","Good","Very Good","Excellent"),
Rating_prop = runif(25))
df$Rating_prop <- ave(df$Rating_prop, df$Variable_name, FUN = function(x) x / sum(x))
# library
library(ggplot2)
# solution
ggplot(df,
aes(x = Rating_prop,
y = reorder(Variable_name, ave(setNames(Rating_prop, Rating), Variable_name, FUN = function(x) replace(x["Excellent"], is.na(x["Excellent"]), 0))),
fill = factor(Rating, levels=c("Poor","Fair","Good","Very Good","Excellent"))))
geom_col(position ="fill", width = 0.8)
scale_fill_manual("legend", values = c("Excellent" = "#275E6B", "Very Good" = "#4AAAC4", "Good" = "#8CD4E5", "Fair" = "#F7963D", "Poor" = "#BE2327"))
geom_text(aes(label=scales::percent(Rating_prop, accuracy = 1)),
position=position_fill(vjust=0.5), color="white", size=9)
labs(y = "Variable_name")
scale_x_continuous(labels = scales::percent)
theme_classic()

Created on 2021-11-11 by the reprex package (v2.0.0)
I tried to simplify a bit your code:
- I used
scales::percentinstead ofpaste - I used
geom_colinstead ofgeom_bar, with allows me to remove thestat = "identity"argument - I removed
coord_flipand I simply switchedxandy
Also, as final touches:
- I added
scale_x_continuousso to have percentages on the x axis - I added a
theme

