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

移除NA后ggplot facet_grid柱状图宽度异常问题求解

问题描述

使用ggplot绘制柱状图时,包含NA的完整数据集生成的图表显示正常,但使用na.omit()移除NA值后,柱状图宽度明显变大。即使提前筛选数据、使用facet_wrap或在facet_grid中添加space='free',问题仍会出现。

示例数据集:

District<-c('Ngorongoro','Ngorongoro','Ngorongoro','Misungwi','Misungwi','Mwanga')
Q2<-rep('Retail outlet', 6) 
Q42<-c('once_per_month','once_per_year','once_per_month',NA,NA,NA)
anm<-as.data.frame(cbind(District,Q2,Q42))

完整数据绘图代码:

anm$Q42<-factor(anm$Q42,levels=c('once_per_week','once_per_month',
                                 'once_per_6months','once_per_year'))
ggplot(data = anm, aes(x=Q42,fill=District)) +
  geom_bar() +
  scale_x_discrete(drop=F)+
  scale_fill_discrete(drop=F)+
  labs(title="Animal health providers", 
       subtitle='n=3',x="", y="Count") +
  facet_grid(~Q2)+
  ylim(0,6)+
  theme(axis.text.x = element_text(angle = 90, hjust=1),
        plot.title = element_text(face='bold'),
        text=element_text(size=10))+
  stat_count(geom='text',aes(label = ..count..,group=1),vjust=-2,size=2)+
  stat_count(geom='text',aes(label = paste0("(",round(..count..*100/3,1),"%)"),group=1),vjust=-0.5,size=2)

移除NA后绘图代码:

ggplot(data = na.omit(anm), aes(x=Q42,fill=District)) +
  geom_bar() +
  scale_x_discrete(drop=F)+
  scale_fill_discrete(drop=F)+
  labs(title="Animal health providers", 
       subtitle='n=3',x="", y="Count") +
  facet_grid(~Q2)+
  ylim(0,6)+
  theme(axis.text.x = element_text(angle = 90, hjust=1),
        plot.title = element_text(face='bold'),
        text=element_text(size=10))+
  stat_count(geom='text',aes(label = ..count..,group=1),vjust=-2,size=2)+
  stat_count(geom='text',aes(label = paste0("(",round(..count..*100/3,1),"%)"),group=1),vjust=-0.5,size=2)
问题原因

核心原因是ggplot的默认布局逻辑:

  1. 你通过scale_x_discrete(drop=F)强制保留了Q42的所有4个因子水平,即使部分水平没有数据。
  2. 当使用na.omit()删除NA行后,数据中仅剩下2个Q42水平有实际观测值,ggplot会自动调整有数据的柱子宽度,使其填充更多面板可用空间(避免空水平导致面板过于稀疏)。
  3. 而完整数据中存在的NA行,虽然不会被绘制到x轴上,但会影响ggplot的布局计算,使其维持默认的柱子宽度比例。
解决方法

只需在geom_bar()中手动指定固定的柱子宽度,即可确保两种情况下的柱子宽度一致。具体步骤如下:

修改移除NA后的绘图代码,在geom_bar()中添加width参数(比如设置为0.6,可根据需求调整):

ggplot(data = na.omit(anm), aes(x=Q42,fill=District)) +
  geom_bar(width = 0.6) +  # 手动设置柱子宽度
  scale_x_discrete(drop=F)+
  scale_fill_discrete(drop=F)+
  labs(title="Animal health providers", 
       subtitle='n=3',x="", y="Count") +
  facet_grid(~Q2)+
  ylim(0,6)+
  theme(axis.text.x = element_text(angle = 90, hjust=1),
        plot.title = element_text(face='bold'),
        text=element_text(size=10))+
  stat_count(geom='text',aes(label = ..count..,group=1),vjust=-2,size=2)+
  stat_count(geom='text',aes(label = paste0("(",round(..count..*100/3,1),"%)"),group=1),vjust=-0.5,size=2)

你也可以将完整数据的绘图代码也加上相同的width参数,确保两张图的柱子宽度完全一致。

内容的提问来源于stack exchange,提问作者Kathrin Loosli

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 13:18:04