I need to plot means and standard errors for 4 variables grouped by 2 (left vs. right hand). Here are the data:
left_start_mydata = read.table(text="condition force
right_small 1.80523635404968
right_small 2.6420765093878
right_small -0.814658993753841
right_small -2.60104096307957
right_small -1.98589533137477
right_small 3.40251831946075
right_small -0.320129242153803
right_small -2.98033170716285
right_small 1.89317065279704
right_small -3.84882524848594
right_small -3.98968367934259
right_small 1.10427581334271
right_large -1.75347355221301
right_large 0.791286271808679
right_large -2.0073148173165
right_large -5.03908061365724
right_large -3.21618785397385
right_large 3.15958835997412
right_large -0.728320450803572
right_large -0.754841068944837
right_large 1.26489177600709
right_large -1.25150854925629
right_large 2.91927950249639
right_large 0.343070062995591
left_small 2.76611178207954
left_small 1.98555350876524
left_small 1.90443573003935
left_small 0.939363367617274
left_small 1.47248738494375
left_small -1.04761679029031
left_small -0.824572467883381
left_small -1.54423800803017
left_small 1.5187848305815
left_small 1.0956007263072
left_small 3.89244539291397
left_small 1.72801660622873
left_large 0.902501901614639
left_large 2.89567274148723
left_large -0.503732000967399
left_large -2.87429518370343
left_large -1.85785327815289
left_large -4.73265776308004
left_large -0.752958593136438
left_large 2.47010977406911
left_large -1.19149141260447
left_large -0.396960252581726
left_large 1.54175722591051
left_large 2.05533917545533
",header=TRUE)
At the next step, I calculate descriptive statistics for each condition:
attach(left_start_mydata)
left_start_mean_force = tapply(force, INDEX=condition, mean) #means
left_start_sem_force = tapply(force,INDEX=condition,sd)/ sqrt(tapply(force,condition, length) ) #stand_errors
Now I plot:
barcols = c("red","blue")
sapply(2,
function(x) {
mids = barplot(matrix(left_start_mean_force,
nrow=2,
byrow=TRUE),
ylim=c(-2,3),
beside=TRUE,
col=barcols)
axis(1,at=colMeans(mids),
c("left hand","right hand"),lwd=0,lwd.tick=0)
abline(h=0)
arrows(mids, left_start_mean_force - left_start_sem_force,
mids, left_start_mean_force + left_start_sem_force,
code = 3,
angle = 90,
length = 0.1,
lwd = 2)
}
)
And I get almost what I need (see the figure below).
BUT! If you look at the bars for the right hand, you can see that the red one (which should represent condition "right_large") is actually lower than the blue bar next to it ("right_small"), whereas the actual value is higher (i.e., closer to zero):
> left_start_mean_force
left_large left_small right_large right_small
1.2812381 -0.6430682 -0.5242566 -0.6063786
It seems that somehow these two columns were shuffled. The problem only appears for mean values. Standard errors are represented correctly, i.e., "right_large" is shown on the left, and "right_small" on the right side.
What is the problem? I assume, it must be something either with the barplot function of with sapply.
P.S.: please don't suggest me ggplot and other packages, I'm sure there's a simple soluton with standard functions.
Your data is grouped incorrectly. You need to set byrow
to FALSE
in this part of the code:
mids = barplot(matrix(left_start_mean_force,
nrow=2,
byrow=FALSE), # <<<<<< HERE
ylim=c(-2,3),
beside=TRUE,
col=barcols)
When you pass a matrix to barplot
, it groups values by column, not row.
m = matrix(1:4, nrow=2)
barplot(m, beside=T)
# m is:
# 1 3
# 2 4
On the other hand, what you are doing is similar to this:
m = matrix(1:4, nrow=2, byrow=T)
barplot(m, beside=T)
# m is:
# 1 2
# 3 4