You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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, and scale_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:

  1. Precompute relative frequencies per facet: Use dplyr to calculate the percentage of each category within its own dimension (key)
  2. Let facets have independent x-axes: Remove the forced drop=FALSE and use scales="free_x" in facet_wrap() so each facet only shows categories relevant to it
  3. Use geom_col() instead of geom_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 by key + value to 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(): Unlike geom_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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:38:30