0

I have my dataframe as:

T_ID   S1    S2
1      21    26
1      20    25
1      21    22
2      20    53
2      41    62
2      30    23

I have plotted the S1 and S2 in a same graph as per T_ID(T_ID "1" have one color, T_ID "2" have one color so on..). Now I want to plot the Standard deviation as per T_IDs in the same graph. I can't figure out how to do this..

ayush
  • 343
  • 3
  • 20
  • 2
    You could get the `sd` per group for each column by `aggregate(.~T_ID, df1, sd)` Also check [here](http://stackoverflow.com/questions/17660278/how-to-plot-treatment-means-in-ggplot2) – akrun Jun 19 '15 at 05:04

2 Answers2

1

The answer I am providing uses three packages: tidyr, dplyr and ggplot2. It's a bit hacky, but I think it gives you the desired output but requires you to get the data into the right format and calculating your desired values to to define aesthetics prior to plotting it - a typical thing for ggplot2. If someone else has an easier way of doing this, I'd love to see it, right now this is the best I could come up with given the data provided.

First, get your data into the right format (assuming your data is called "df"), calculate the mean and standard deviation per time point (T1, T2) and group (S1, S2), then plot the barplot with errorbars representing mean +/- SD.

require(tidyr)
require(dplyr)
require(ggplot2)

df2 <- df %>% gather(group, measurement, S1:S2)
df3 <- df2 %>% group_by(T_ID, group) %>% mutate(sd = sd(measurement), m = mean(measurement))
gg1 <- ggplot(df3, aes(x=group, y=measurement, fill=factor(T_ID)))
gg1 + geom_bar(width=0.4, position=position_dodge(width=0.5), stat="identity")+geom_errorbar(aes(ymin=m-sd, ymax=m+sd), position=position_dodge(width=0.5), width=0.4, size=0.1)

Gives you the following

enter image description here

EDIT FOLLOWING OPS SPECIFICATIONS

First attempt that didn't work.

df4 <- df %>% group_by(T_ID) %>% mutate(SD1 = sd(S1)) %>% mutate(SD2 = sd(S2)) %>% mutate(mean_s1 = mean(S1)) %>% mutate(mean_s2 = mean(S2))

df4
Source: local data frame [6 x 7]
Groups: T_ID

  T_ID S1 S2        SD1       SD2  mean_s1  mean_s2
1    1 21 26  0.5773503  2.081666 20.66667 24.33333
2    1 20 25  0.5773503  2.081666 20.66667 24.33333
3    1 21 22  0.5773503  2.081666 20.66667 24.33333
4    2 20 53 10.5039675 20.420578 30.33333 46.00000
5    2 41 62 10.5039675 20.420578 30.33333 46.00000
6    2 30 23 10.5039675 20.420578 30.33333 46.00000

gg2 <- ggplot(df4, aes(x=S1, y=S2, fill=factor(T_ID)))
gg2 + geom_point(aes(col=factor(T_ID)))+geom_errorbar(aes(ymin=mean_s1-SD1, ymax=mean_s1+SD2))+geom_errorbarh(aes(xmin=mean_s2-SD2, xmax=mean_s2+S2))

### this doesn't really work...too many error bars mapping all over the place

#create a new data-frame with plotting coordinates for geom_errobar; I tried this because in the help menu it said you could provide a new df to geom_errorbar() to overide plotting aesthetics, but

df2 <- df %>% group_by(T_ID) %>% summarise(mean_s1=mean(S1), sd_s1=sd(S1), mean_s2=mean(S2), sd_s2=sd(S2))
gg2 <- ggplot(df, aes(x=S1, y=S2, group=factor(T_ID), colour=factor(T_ID)))
gg2 + geom_point()+geom_errorbar(aes(ymax=mean_s1+sd_s1, ymin=mean_s1-sd_s1), data=df2)
Error in eval(expr, envir, enclos) : object 'S1' not found

# doesn't work

Second attempt.

EDIT - Possible solution to OPs question

df4 <- df %>% group_by(T_ID) %>% mutate(SD1 = sd(S1)) %>% mutate(SD2 = sd(S2)) %>% mutate(mean_s1 = mean(S1)) %>% mutate(mean_s2 = mean(S2))

    df4
    Source: local data frame [6 x 7]
    Groups: T_ID

      T_ID S1 S2        SD1       SD2  mean_s1  mean_s2
    1    1 21 26  0.5773503  2.081666 20.66667 24.33333
    2    1 20 25  0.5773503  2.081666 20.66667 24.33333
    3    1 21 22  0.5773503  2.081666 20.66667 24.33333
    4    2 20 53 10.5039675 20.420578 30.33333 46.00000
    5    2 41 62 10.5039675 20.420578 30.33333 46.00000
    6    2 30 23 10.5039675 20.420578 30.33333 46.00000
gg2 <- ggplot(df4, aes(x=S1, y=S2, fill=factor(T_ID)))
gg2 + geom_point(aes(col=factor(T_ID)))+
+     geom_errorbar(aes(x=mean_s2, y=mean_s1, ymin=mean_s1-SD1,ymax=mean_s1+SD2, colour=factor(T_ID)))+geom_errorbarh(aes(x=mean_s2, y=mean_s1, xmin=mean_s1-SD1, xmax=mean_s1+SD2, colour=factor(T_ID)))

Provides you with this plot below, where the errorbars are plotted according to longitude and lattitude. I gather with your real data the errorbars will be more aesthetically pleasing to the eye. scatter with xy errobars

OFish
  • 474
  • 1
  • 9
  • 19
  • I want to try this with scatter plot. I have a very large dataset only a sample is provided here. I have already plotted scatter plot for the S1 and S2 as per their groups. Now I want to plot the SD and Covariance over the same plot(scatter plot). It is working but its not what i require. Can you suggest me another sol for this? Thank you. – ayush Jun 19 '15 at 08:09
  • can you please show me an image example and code of what you have achieved until now? – OFish Jun 19 '15 at 08:10
  • a legend would be helpful. Do the colours correspond to time points or groups? And do you want the SD of the whole group or individual points? If the latter, then you have to explain the structure of your dataframe clearer to me. and please edit your post above to show me the code how you got to your desired plot so far. – OFish Jun 19 '15 at 08:18
0

Below is one simple solution assuming your data frame is named df1

means <- apply(df1[,2:3], 2, tapply, df1[,1], mean)
sds <- apply(df1[,2:3], 2, tapply, df1[,1], sd)
m <- barplot(means, beside=TRUE, ylim=c(0, 60), legend=TRUE)
segments(m, means - sds, m, means + sds, lwd=2)

This gives us:

barplot

Karolis Koncevičius
  • 9,417
  • 9
  • 56
  • 89
  • I too thought that's what the OP wants, but re-read the question (even though OP seems to be editing the post occasionally and has removed previous code): OP wants a scatterplot with the SD (and then I assume co-variance) plotted over it. Hence me trying to plot "crossed" SD bar's in ggplot2 as a starting point. Why a PCA or similar isn't performed isn't too clear to me though. – OFish Jun 24 '15 at 08:05