Here’s a simple way to make a bar plot with error bars three ways: standard deviation, standard error of the mean, and a 95% confidence interval. The key step is to precalculate the statistics for ggplot2.
n.per.group<-10 alpha<-0.05 # for a (1.00-alpha)=95% confidence interval # Simulate raw data for an experiment or observational study. data.raw <- data.frame( treatment=rep(c('A','B'), each=n.per.group), value=c(rnorm(n.per.group, 2), rnorm(n.per.group, 3)) ) # This data frame calculates statistics for each treatment. data.summary <- data.frame( treatment=levels(data.raw$treatment), mean=tapply(data.raw$value, data.raw$treatment, mean), n=tapply(data.raw$value, data.raw$treatment, length), sd=tapply(data.raw$value, data.raw$treatment, sd) ) # Precalculate standard error of the mean (SEM) data.summary$sem <- data.summary$sd/sqrt(data.summary$n) # Precalculate margin of error for confidence interval data.summary$me <- qt(1-alpha/2, df=data.summary$n)*data.summary$sem # Load ggplot2 library require(ggplot2) # Use ggplot to draw the bar plot using the precalculated 95% CI. png('barplot-ci.png') # Write to PNG ggplot(data.summary, aes(x = treatment, y = mean)) + geom_bar(position = position_dodge(), stat="identity", fill="blue") + geom_errorbar(aes(ymin=mean-me, ymax=mean+me)) + ggtitle("Bar plot with 95% confidence intervals") + # plot title theme_bw() + # remove grey background (because Tufte said so) theme(panel.grid.major = element_blank()) # remove x and y major grid lines (because Tufte said so) dev.off() # Close PNG # Plot one standard error (standard error of the mean/SEM) png('barplot-sem.png') ggplot(data.summary, aes(x = treatment, y = mean)) + geom_bar(position = position_dodge(), stat="identity", fill="blue") + geom_errorbar(aes(ymin=mean-sem, ymax=mean+sem)) + ggtitle("Bar plot with standard error as error bars") + theme_bw() + theme(panel.grid.major = element_blank()) dev.off() # Plot one standard deviation png('barplot-sd.png') ggplot(data.summary, aes(x = treatment, y = mean)) + geom_bar(position = position_dodge(), stat="identity", fill="blue") + geom_errorbar(aes(ymin=mean-sd, ymax=mean+sd)) + ggtitle("Bar plot with standard deviation as error bars") + theme_bw() + theme(panel.grid.major = element_blank()) dev.off()
The plots:
Tested with R 2.15.2, R 3.0.2, and ggplot2 0.9.3.1. Recently ggplot2 has gone under some changes, and this code won’t work in earlier versions of ggplot2.
Why when you have such an excellent graphing system as ggplot2 do you want to plot a mean with error bars? it is such bad practice. I’ve just done a short post on this at http://sharpstatistics.co.uk/stats/wily-data-analysis/ and if you google dynamite plot you will find plenty more.
I guess you intended to use
data.summary$me <- qt(1- alpha /2, df=data.summary$n)*data.summary$sem
in line 22, right?
You created the alpha paramenter but didn't use it in the rest of the code
Good catch! Fixed.
I have an alternative if you want to have more options. Some comments are in spanish, but the principal idea is english. Enjoy!
Those of us who use
options(stringsAsFactors = FALSE)
need to explicitly make A and B factors
treatment=rep(factor(c(‘A’,’B’)), each=n.per.group)
– Aaron
If you really want to do “dynamite plots” (I like this, LOL) why not simply use barplot() with arrows()?
e.g.
mymean <- tapply(data.raw$value, data.raw$treatment, mean)
mysd <- tapply(data.raw$value, data.raw$treatment, sd)
bp <- barplot(mymean, ylim = c(0,max(mymean+mysd)+.1), main="Dynamite Plots with SD")
arrows(bp,mymean,bp,mymean+mysd, angle = 90)
arrows(bp,mymean,bp,mymean-mysd, angle = 90)
-didi