R / ggplot 2 - dealing uneven group size with Facet_grid and geom histogram / errorbar

errorbar, facet-grid, ggplot2, histogram, r

Solution

You need to use `+ facet_grid(~ sample, scales = "free_x", space = "free_x")`. The `space` argument resizes the facets so that the bar width will be consistent (or more accurately, so that the space between ticks on the X axis will be).

require(dplyr)
data_frame(x = c("a", "a", "b", "b", "c", "c"),
           y = runif(length(x)),
           sample = rep(c("A", "B"), 3),
           grouping = c(1, 1, 1, 1, 2, 2)) %>% 
  ggplot(aes(x, y, fill = sample)) + geom_bar(stat = "identity", position = "dodge") + 
  facet_grid(~grouping, space = "free_x", scales = "free_x")

EDIT:

Sometimes you may find you're missing data and that results in the uneven bars again:

data_frame(x = c("a", "a", "b", "b", "c", "c"),
           y = runif(length(x)),
           sample = rep(c("A", "B"), 3),
           grouping = c(1, 1, 1, 2, 2, 2)) %>% 
  ggplot(aes(x, y, fill = sample)) + geom_bar(stat = "identity", position = "dodge") + 
  facet_grid(~grouping, space = "free_x", scales = "free_x")

The fix for that is the `tidyr` package which lets you include explicit `NA` values, which make a space for a bar that's missing.

data_frame(x = c("a", "a", "b", "b", "c", "c"),
           y = runif(length(x)),
           sample = rep(c("A", "B"), 3),
           grouping = c(1, 1, 1, 2, 2, 2)) %>% 
  group_by(grouping) %>% 
  tidyr::complete(crossing(sample, x)) %>% 
  ggplot(aes(x, y, fill = sample)) + geom_bar(stat = "identity", position = "dodge") + 
  facet_grid(~grouping, space = "free_x", scales = "free_x")

Problem

I'd like to force facetting with `+facet_grid(.~sample,scales = "free_x")` at the very last line of my code but the result looks quite inesthetic (see graph2) (in my humble opinion). I was wondering if there was a way to force a specific size for each bar of geom_histogram sothat bars would look alike between groups whether groups are balanced or not. Thanks, Vivian sample data : ``` samplenote prod N mean sd se sampleprod sample Sample A PRODUCT A 3 0.562103162 0.120039901 0.069305069 Sample A PRODUCT A Sample A Sample A PRODUCT B 3 0.516322045 0.039250354 0.022661203 Sample A PRODUCT B Sample A Sample B PRODUCT A 3 0.504789098 0.055005623 0.031757511 Sample B PRODUCT A Sample B Sample B PRODUCT B 3 0.564334594 0.035685751 0.020603178 Sample B PRODUCT B Sample B Sample C PRODUCT A 3 0.337747481 0.042670562 0.024635861 Sample C PRODUCT A Sample C Sample C PRODUCT B 3 0.470207809 0.012102641 0.006987463 Sample C PRODUCT B Sample C Sample C group1 PRODUCT A 3 0.666033925 0 0 Sample C group1 PRODUCT A Sample C Sample C group1 PRODUCT B 3 0.775242276 0.017019353 0.009826128 Sample C group1 PRODUCT B Sample C Sample C group2 PRODUCT A 3 0.53594287 0.062336653 0.035990084 Sample C group2 PRODUCT A Sample C Sample C group2 PRODUCT B 3 0.4705616 0.009122911 0.005267115 Sample C group2 PRODUCT B Sample C ``` Exemple graph 1 : ``` ggplot(data=test.df,aes(x=samplenote,y=mean,fill=prod))+ geom_bar(stat="identity",col="black",size = 0.4,position='dodge')+ scale_fill_manual(values=c("#B50000","#0039e6"))+ geom_errorbar(data=test.df,aes(x=samplenote,ymax=mean+sd,ymin=mean,width=.2),position=position_dodge(.9),colour="black",size = 0.4)+ theme_classic()+ theme(axis.text=element_text(colour="black"))+ theme(axis.ticks=element_line(colour="black"))+ coord_cartesian(ylim=c(0,1.13),expand = TRUE)+ scale_y_continuous(expand=c(0,0),breaks=c(0,0.25,0.5,0.75,1))+ ylab("g/g prod")+ xlab("")+ theme(legend.title=element_blank())+ theme(axis.line=element_line(size=0.4)) ``` graph1 graph2 EDIT Solution given by Brian : ``` ggplot(data=test.df,aes(x=samplenote,y=mean,fill=prod))+ geom_bar(stat="identity",col="black",size = 0.4,position='dodge')+ scale_fill_manual(values=c("#B50000","#0039e6"))+ geom_errorbar(data=test.df,aes(x=samplenote,ymax=mean+sd,ymin=mean,width=.2),position=position_dodge(.9),colour="black",size = 0.4)+ theme_classic()+ theme(axis.text=element_text(colour="black"))+ theme(axis.ticks=element_line(colour="black"))+ coord_cartesian(ylim=c(0,1.13),expand = TRUE)+ scale_y_continuous(expand=c(0,0),breaks=c(0,0.25,0.5,0.75,1))+ ylab("g/g prod")+ xlab("")+ theme(legend.title=element_blank())+ theme(axis.line=element_line(size=0.4))+facet_grid(.~sample,scales = "free_x",space="free_x") ``` giving graph3

Original source