Edit: Based on comments below I decided to be more explicit. So here is an example of the data I am working on.
A B outcome
1 2.31 1.47 Y
2 2.14 1.32 N
3 3.49 1.00 Y
4 2.12 0.62 Y
5 0.47 0.55 N
6 3.36 0.50 N
7 3.50 0.33 Y
8 1.97 0.39 Y
9 3.12 0.99 N
10 2.04 0.89 Y
11 2.78 0.36 Y
12 1.83 0.70 N
13 3.53 0.77 N
14 2.25 0.39 N
15 1.67 0.43 N
16 3.09 1.10 Y
> dataset <- example_data
> means1<- tapply(A,outcome,function(x) mean(x,na.rm=TRUE))
> means2<- tapply(B,outcome,function(x) mean(x,na.rm=TRUE))
> std.err1<- tapply(A,outcome,function(x)sd(x,na.rm=TRUE)/sqrt(length(na.omit(x))))
> std.err2<- tapply(B,outcome,function(x)sd(x,na.rm=TRUE)/sqrt(length(na.omit(x))))
> matrix_means<- matrix(c(means1,means2),byrow = TRUE)
> graph<- barplot(matrix_means, beside=TRUE, space=c(0.2,0,0.2,0), axes=FALSE, ann=FALSE, col=c("white","black","red","blue"),ylim=c(0,4), names=c("Outcome-N","Outcome-Y","Outcome-N","Outcome-Y"), xpd=FALSE)
> axis(2, cex.axis=1.5)
> arrows(graph, means1, graph, means1 + std.err1, graph, means2, graph, means2 + std.err2, code=3, angle=90, length=0.1)
R.S. is correct, if you make an MCVE it would be a lot easier for us to understand your problem and see how to help. If your data set is very large and it's hard to make a sensible subset of it, the preloaded datasets can come in handy. You can get a list of what's available by running
In this case your question is pretty general and from what you write you're already more than half-way there.
graph object you've made contains the relevant x-values. With the mean and SEM values you already know where the arrows should start and how far they should extend, so all you have to do is to pass this information to the
arrow function as vectors, and you're golden.
As you haven't supplied any data to work with I'll use the
mtcars dataset to demonstrate.
data(mtcars) summ.df <- data.frame( mean=tapply(mtcars$hp, mtcars$cyl, mean), sd=tapply(mtcars$hp, mtcars$cyl, sd), n=tapply(mtcars$hp, mtcars$cyl, length)) summ.df$sem <- summ.df$sd/sqrt(summ.df$n) par(mar=c(2.5, 2.5, 2, 1.5)) bplt <- barplot(summ.df$mean, col="white") arrows(bplt, summ.df$mean+summ.df$sem, bplt, summ.df$mean-summ.df$sem, angle=90, code=3, xpd=NA, length=0.1)
In reply to the update
The call to
arrows is what's causing you trouble. If you read the documentation (
?arrows) you'll see that the four first arguments are x and y coordinates for the start and end points of the arrows. For each arrow the start and end x values are the same (they're entirely vertical) and given by
graph, while the end and start y values are given by the mean ± SEM, respectively.
As such you'll get the correct result by calling
arrows(graph, c(means1, means2) + c(std.err1, std.err2), graph, c(means1, means2) - c(std.err1, std.err2), code=3, angle=90, length=0.1)