HCAI
HCAI

Reputation: 2263

Errorbars in r of two groups ggplot2

I'd like to plot standard deviations of the mean(z)/mean(b) which are grouped by two factors $angle and $treatment:

z= Tracer angle treatment 60 0 S 51 0 S 56.415 15 X 56.410 15 X

b=Tracer angle treatment 21 0 S 15 0 S 16.415 15 X 26.410 15 X

enter image description here So far I've calculated the mean for each variable based on angle and treatment:

aggmeanz <-aggregate(z$Tracer, list(angle=z$angle,treatment=z$treatment), FUN=mean) aggmeanb <-aggregate(b$Tracer, list(angle=b$angle,treatment=b$treatment), FUN=mean)

It now looks like this: aggmeanz angle treatment x 1 0 S 0.09088021 2 30 S 0.18463353 3 60 S 0.08784315 4 80 S 0.09127198 5 90 S 0.12679296 6 0 X 2.68670392 7 15 X 0.50440692 8 30 X 0.83564470 9 60 X 0.52856956 10 80 X 0.63220093 11 90 X 1.70123025

But when I come to plot it, I can't quite get what I'm after

ggplot(aggmeanz, aes(x=aggmeanz$angle,y=aggmeanz$x/aggmeanb$x, colour=treatment)) + 
  geom_bar(position=position_dodge(), stat="identity") +
  geom_errorbar(aes(ymin=0.1, ymax=1.15),
                width=.2,                    
                position=position_dodge(.9))  +
  theme(panel.grid.minor = element_blank()) +
  theme_bw()

EDIT:

dput(aggmeanz)
structure(list(time = structure(c(1L, 3L, 4L, 5L, 6L, 1L, 2L, 
3L, 4L, 5L, 6L), .Label = c("0", "15", "30", "60", "80", "90"
), class = "factor"), treatment = structure(c(1L, 1L, 1L, 1L, 
1L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("S", "X"), class = "factor"), 
    x = c(56.0841582902523, 61.2014237854156, 42.9900742785269, 
    42.4688447229277, 41.3354173870287, 45.7164231791512, 55.3943182966382, 
    55.0574951462903, 48.1575625699563, 60.5527200655174, 45.8412287451211
    )), .Names = c("time", "treatment", "x"), row.names = c(NA, 
-11L), class = "data.frame")

> dput(aggmeanb)
structure(list(time = structure(c(1L, 3L, 4L, 5L, 6L, 1L, 2L, 
3L, 4L, 5L, 6L), .Label = c("0", "15", "30", "60", "80", "90"
), class = "factor"), treatment = structure(c(1L, 1L, 1L, 1L, 
1L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("S", "X"), class = "factor"), 
    x = c(56.26325504249, 61.751655279608, 43.1687113436753, 
    43.4147408285209, 41.9113698082799, 46.2800894420131, 55.1550995335947, 
    54.7531592595068, 47.3280215294235, 62.4629068516043, 44.2590192583692
    )), .Names = c("time", "treatment", "x"), row.names = c(NA, 
-11L), class = "data.frame")

EDIT 2: I calculated the standard dev as follows:

aggstdevz <-aggregate(z$Tracer, list(angle=z$angle,treatment=z$treatment), FUN=std) aggstdevb <-aggregate(b$Tracer, list(angle=b$angle,treatment=b$treatment), FUN=std)

Any thoughts would be much appreciated,

Cheers

Upvotes: 1

Views: 1672

Answers (2)

Szasulja
Szasulja

Reputation: 85

Think about the problem in two steps:

  1. create a data frame (say data) which contains all the information you would like to visualize. In this case, this seems to be the two factors (angle, treatment), the mean group differences (say dif) and standard errors (say ste).
  2. visualize this information.

Step 2) will be easy. This should probably produce something very similar to your sketch.

ggplot(data, aes(x=angle, y=dif, colour=treatment)) + 
     geom_point(position=position_dodge(0.1)) + 
     geom_errorbar(aes(ymin=dif-ste, ymax=dif+ste), width=.1, position=position_dodge(0.1)) + 
     theme_bw()

However, at this point, you do not provide enough information to get help with Step 1. Try to include code which produces your original data (or the type of data you have) instead of copy-pasting chunks of your data output or pasting the aggregated data which lacks standard errors.

Combining your two aggregated data frames and generating random numbers for standard error produces the graph below:

#I imported your two aggregated data frames from your dput output.
data <- cbind(aggmeanb, aggmeanz$x, rnorm(11))
names(data) <- c("angle", "treatment", "meanz", "meanb", "ste")
data$dif <- data$meanz - data$meanb 

plot demonstration with randomly generated confidence intervals

Upvotes: 2

Nancy
Nancy

Reputation: 4089

As others have noted, you'll need to join the two dataframes together. There are also some little quirks in the dput data you showed, so I've renamed some columns to make sure that they join appropriately and match what you've attempted. NOTE: You'll need name the two means differently so that they don't get merged together or cause conflicts.

names(aggmeanb)[names(aggmeanb) == "x"] = "mean_b"
names(aggmeanb)[names(aggmeanb) == "time"] = "angle"
names(aggmeanz)[names(aggmeanz) == "x"] = "mean_z"
names(aggmeanz)[names(aggmeanz) == "time"] = "angle"

joined_data = join(aggmeanb, aggmeanz)
joined_data$divmean = joined_data$mean_b/joined_data$mean_z

> head(joined_data)
  angle treatment   mean_b   mean_z divmean
1     0         S 56.26326 56.08416 1.003193
2    30         S 61.75166 61.20142 1.008991
3    60         S 43.16871 42.99007 1.004155
4    80         S 43.41474 42.46884 1.022273
5    90         S 41.91137 41.33542 1.013934
6     0         X 46.28009 45.71642 1.012330


ggplot(joined_data, aes(factor(angle), divmean)) + 
  geom_boxplot() + 
  theme(panel.grid.minor = element_blank()) +
  theme_bw()

enter image description here

It might be that the data you've included is just a bit of your real data set, but as is there's only one data point per angle-treatment group. However, when you are using a fuller dataset, you can try something like:

ggplot(joined_data, aes(factor(angle), diffmean, group = treatment)) + 
  geom_boxplot() + 
  facet_grid(.~angle, scales = "free_x")

That will group the boxes by angle and then allow you to fill them by treatment.

enter image description here

Upvotes: 3

Related Questions