I have the following data:
dput(test_mod3)
And I draw barplot for it by doing:
ggplot(data=test_mod3, aes(x = as.factor(realDist), y = 1-value, fill=as.factor(clusteringDistance), width=0.75 ) ) +
stat_summary( fun.y=mean, geom="bar", width=0.1, color="black", size=0.2, position=position_dodge(width = 0.90) ) +
stat_summary( fun.data=mean_cl_normal,geom="errorbar", width=0.35, size=0.3, position=position_dodge(width = 0.90))
and this gives me the following bars:

I would like to have all the bars in the same size, although there is no bars to plot for the x=100. So the only bar appearing for x=100 should be same width like the other ones
To achieve that I tried something like:
rd_100 <- c(100, 100, 100, 100, 100)
val_100 = c(1,1,1,1,1)
cd_100 = c(200,300,400,500,550)
df_100 = data.frame(rd_100, val_100, cd_100)
names(df_100) <- names(test_mod2)
test_mod2 <- rbind(test_mod2, df_100)
However this gave me enormous confidence intervals, but the width was OK...
Is there any other way to have equal width bars while using stat_summary()?
Instead of summarising inside ggplot2 with stat_summary, we precalculate those values and we will add the missing groups for realDist = 100 as NAs to achieve the same width later.
First, we use dplyr to group the data and summarise by the mean and the lower and upper limits of the population mean using mean_cl_normal.
library(dplyr)
df <- test_mod3 %>%
group_by(realDist, clusteringDistance) %>%
summarise(mean = mean(value), ymin = mean_cl_normal(value)$ymin,
ymax = mean_cl_normal(value)$ymax)
Output:
realDist clusteringDistance mean ymin ymax
1 10 100 0.9997100 0.9996082 0.9998118
2 10 200 0.9963526 0.9959486 0.9967567
3 10 300 0.9860415 0.9850053 0.9870777
4 10 400 0.9711180 0.9695458 0.9726903
5 10 500 0.9496824 0.9471561 0.9522088
6 10 550 0.9632924 0.9606701 0.9659147
7 100 100 0.9877920 0.9867590 0.9888251
Then we take care of the missing groups. We create all the combinations of realDist and clusteringDistance.
df <- rbind(df, cbind(expand.grid(realDist = levels(as.factor(df$realDist)),
clusteringDistance = levels(as.factor(df$clusteringDistance))),
mean = NA, ymin = NA, ymax = NA))
Output:
realDist clusteringDistance mean ymin ymax
1 10 100 0.9997100 0.9996082 0.9998118
2 10 200 0.9963526 0.9959486 0.9967567
3 10 300 0.9860415 0.9850053 0.9870777
4 10 400 0.9711180 0.9695458 0.9726903
5 10 500 0.9496824 0.9471561 0.9522088
6 10 550 0.9632924 0.9606701 0.9659147
7 100 100 0.9877920 0.9867590 0.9888251
8 10 100 NA NA NA
9 100 100 NA NA NA
10 10 200 NA NA NA
11 100 200 NA NA NA
12 10 300 NA NA NA
13 100 300 NA NA NA
14 10 400 NA NA NA
15 100 400 NA NA NA
16 10 500 NA NA NA
17 100 500 NA NA NA
18 10 550 NA NA NA
19 100 550 NA NA NA
Finally, we plot the data using geom_bar with stat = "identity" and geom_errorbar
ggplot(data=df, aes(x = as.factor(realDist), y = 1-mean, fill=as.factor(clusteringDistance), width=0.75 )) +
geom_bar(stat = "identity", position=position_dodge(width = 0.90), color="black", size=0.2)+
geom_errorbar(aes(ymin=1-ymin, ymax=1-ymax), width=.35, size=0.3, position=position_dodge(.9))

You can achieve something close to what you're looking for with faceting:
ggplot(data=test_mod3, aes(x = as.factor(clusteringDistance), y = 1-value, fill=as.factor(clusteringDistance), width=0.75 ) ) +
stat_summary( fun.y=mean, geom="bar", width=0.1, color="black", size=0.2, position=position_dodge(width = 0.90) ) +
stat_summary( fun.data=mean_cl_normal,geom="errorbar", width=0.35, size=0.3, position=position_dodge(width = 0.90)) +
facet_grid(. ~ realDist)

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With