如何用melt和ggplot绘制分区间堆叠百分比条形图(含分组)
Solution for Flip Stacked Bar Chart with Interval Coloring & Faceting
Hey there! Let's fix up your stacked bar chart to meet all your requirements. Here's a complete, working code example first, followed by breakdowns of each key step:
Complete Working Code
library(ggplot2) library(reshape2) library(scales) # Original data with added group variable (8 individuals split into 2 groups) Data <- data.frame( LMX = c(1.92, 2.33, 3.52, 5.34, 6.07, 4.23, 3.45, 5.64), Thriving = c(4.33, 6.54, 6.13, 4.85, 4.26, 6.32, 5.63, 4.55), Wellbeing = c(1.92, 2.33, 3.52, 2.34, 4.07, 3.23, 3.45, 4.64), Group = rep(c("Group A", "Group B"), each = 4) # Adjust group labels to match your actual data ) rownames(Data) <- 1:8 # Melt data while preserving the Group variable Data_A <- melt(Data, id.vars = c("Group"), measure.vars = c("LMX", "Thriving", "Wellbeing")) # Create numerical interval groups with specified ranges Data_A$value_range <- cut( Data_A$value, breaks = c(0, 1.99, 3.99, 5.99, 7), labels = c("0-1.99", "2-3.99", "4-5.99", "6-7"), include.lowest = TRUE, ordered_result = TRUE # Ensure intervals are sorted in low-to-high order ) # Sort x-axis variables by total value (adjust if you want a different sort logic) Data_A$variable <- factor( Data_A$variable, levels = names(sort(colSums(Data[, c("LMX", "Thriving", "Wellbeing")]))) ) # Plot the flipped stacked bar chart ggplot(Data_A, aes(x = variable, y = value, fill = value_range)) + geom_bar(position = position_fill(reverse = FALSE), stat = "identity") + scale_y_continuous(labels = percent_format()) + scale_fill_manual( values = c("0-1.99" = "yellow", "2-3.99" = "orange", "4-5.99" = "red", "6-7" = "green"), name = "Value Range" ) + coord_flip() + facet_grid(. ~ Group) # Use `Group ~ .` for vertical facets instead
Key Fixes & Explanations
1. Preserve Group Variable During Data Reshaping
- We added a
Groupcolumn directly to the original data frame (tweak the labels to match your actual grouping). - When using
melt(), we setid.vars = c("Group")to keep this variable intact, so we can usefacet_grid()later without losing group information.
2. Bin Values Into Specified Intervals
- The
cut()function lets us split values into your exact ranges:breaksdefines the boundary points of each intervalordered_result = TRUEensures intervals are treated as an ordered factor, so they stack in low-to-high orderinclude.lowest = TRUEmakes sure values exactly equal to the lower bound (like 1.92) are included in the correct interval
3. Sort Variables (As Requested)
- We converted
variableto a factor with levels sorted by the total sum of each variable. This makes the flipped bars appear in low-to-high order based on their total values. If you want a different sort order, just adjust thelevelsargument here.
4. Correct Stacking & Coloring
position_fill(reverse = FALSE)keeps the interval stacking order consistent with your range sequence (flip toTRUEif you want the opposite order)scale_fill_manual()maps each interval to your specified colors, with a clear legend titlecoord_flip()converts the chart to horizontal bars as you requested
5. Facet by Group
facet_grid(. ~ Group)splits the chart into side-by-side facets for each group. Swap tofacet_grid(Group ~ .)if you prefer vertical facets instead.
内容的提问来源于stack exchange,提问作者Andreas G.
相关产品推荐
相关产品推荐

