使用ggplot绘制多分类变量相对频率分面柱状图遇问题求助
Fix: ggplot Faceted Bar Chart Showing All Categories (Making Plot Unusable)
Hey there, let's sort out this issue with your faceted bar chart! The problem you're seeing—all categories showing up in every facet even when they don't belong to that dimension—happens for a couple of key reasons:
- After
gather()ing your data, all category values get pooled together, andscale_x_discrete(drop=FALSE)forces ggplot to keep every single category across all facets, resulting in those empty, useless bars. - Using ggplot's internal
..count..variables can be tricky for per-facet calculations, since it doesn't explicitly tie counts to each facet's group.
Here's the Fix (Step-by-Step)
We'll restructure the workflow to calculate relative frequencies before plotting, which gives you full control over what each facet displays:
- Precompute relative frequencies per facet: Use dplyr to calculate the percentage of each category within its own dimension (key)
- Let facets have independent x-axes: Remove the forced
drop=FALSEand usescales="free_x"infacet_wrap()so each facet only shows categories relevant to it - Use
geom_col()instead ofgeom_bar(): Since we're plotting pre-calculated values,geom_col()is the right tool here
Corrected Code
library(tidyverse) library(scales) data %>% na.omit() %>% gather(key = "key", value = "value") %>% mutate(key = str_sub(key, start = 16)) %>% # Calculate relative frequencies per facet (key) group_by(key) %>% mutate(total_responses = n()) %>% group_by(key, value) %>% mutate(rel_freq = n() / total_responses) %>% ungroup() %>% # Build the plot ggplot(aes(x = value, y = rel_freq)) + geom_col(fill = "#3498db") + # Custom fill color (optional) scale_y_continuous(labels = percent, limits = c(0, 1)) + ylab("Relative Frequencies (%)") + xlab("") + facet_wrap(~ key, scales = "free_x") + # Critical: let x-axes be facet-specific theme_bw() + theme( axis.text.x = element_text(angle = 90, hjust = 0.9), strip.text = element_text(size=6) )
Key Explanations
- Precomputing frequencies: By grouping first by
key(your facet dimension) to get total responses per facet, then grouping bykey + valueto get category counts, we ensure the relative frequency is calculated only within each facet's data. No more cross-facet category leakage! scales="free_x": This tells ggplot to let each facet have its own unique x-axis, showing only the categories that exist in that facet's data. Goodbye empty bars!geom_col(): Unlikegeom_bar()(which counts data on-the-fly),geom_col()plots pre-calculated y-values—perfect for our already computed relative frequencies.
This should give you exactly what you want: 4 facets, each showing only the categories for its dimension, with accurate relative frequencies.
内容的提问来源于stack exchange,提问作者Alberto Stefanelli
相关产品推荐
相关产品推荐

