Search code examples
rggplot2vegan

Barplot with SError from table


I am trying to plot grouped barplots from a table I generated, below.

Group.1                S.obs     se.obs    S.chao1   se.chao1
Cliona celata complex  499.7143  59.32867  850.6860  65.16366
Cliona viridis         285.5000  51.68736  462.5465  45.57289
Dysidea fragilis       358.6667  61.03096  701.7499  73.82693
Phorbas fictitius      525.9167  24.66763  853.3261  57.73494

So far, I have tried the following with no good results:

library(dplyr)
library(tidyr)
library(ggplot2)

data.frame(t(agg_media)) %>%
add_rownames() %>%
gather(group, value, - c(rowname, se.chao1)) -> media_2
gather(group, value, - c(rowname, se.obs)) -> media_3

#take out error bars from S.obs
# mutate(media2, se.chao1 = replace(se.chao1, which(group == "S.obs"),NA)) -> media3

dodge <- position_dodge(width=0.9)

g <- ggplot(data = agg_media, aes(x = rowname, y = value, fill = group)) +
   geom_bar(position = "dodge", stat = "identity") + 
   geom_errorbar(data = media_2, aes(ymax = value + se.chao1, ymin = value - se.chao1),
            position = dodge, width = 0.25) +
   geom_errorbar(data = media_3, aes(ymax = value + se.obs, ymin = value - se.obs),
            position = dodge, width = 0.25) +
 labs(x = "Sponge Species", y = "Averaged OTU Richness") +
 scale_y_continuous(expand = c(0,0))

ggsave(g, file = "Obs_Est_OTUs.svg")

The point is to take se.obs as the standard error for S.obs and se.chao1 as the standard error for S.chao1 and plot them as a grouped barplot...

What am I doing wrong here?


Solution

  • Is this what you want?

    Load your data snippet:

    txt <- '"Group.1"                "S.obs"   "se.obs"  "S.chao1" "se.chao1"
    "Cliona celata complex"  499.7143  59.32867  850.6860  65.16366
    "Cliona viridis"         285.5000  51.68736  462.5465  45.57289
    "Dysidea fragilis"       358.6667  61.03096  701.7499  73.82693
    "Phorbas fictitius"      525.9167  24.66763  853.3261  57.73494'
    
    dat <- read.table(text = txt, header = TRUE)
    

    and load some packages. In particular, I'm going to use tidyr for the data manipulation which doesn't really suit the melt-cast or reshape concepts

    library("ggplot2")
    library("tidyr")
    

    These three steps get the data in a suitable format. First we gather the variables, which is like melt() but we need to tell it which variable to not gather, i.e. which variable is an id variable

    mdat <- gather(dat, S, value, -Group.1)
    

    S is the column I want to create containing the variable names, value is the name of the column I want to create that contains the data from the columns selected, and - Group.1 means work on all columns except group.1. This gives:

                     Group.1        S     value
    1  Cliona celata complex    S.obs 499.71430
    2         Cliona viridis    S.obs 285.50000
    3       Dysidea fragilis    S.obs 358.66670
    4      Phorbas fictitius    S.obs 525.91670
    5  Cliona celata complex   se.obs  59.32867
    6         Cliona viridis   se.obs  51.68736
    7       Dysidea fragilis   se.obs  61.03096
    8      Phorbas fictitius   se.obs  24.66763
    9  Cliona celata complex  S.chao1 850.68600
    10        Cliona viridis  S.chao1 462.54650
    11      Dysidea fragilis  S.chao1 701.74990
    12     Phorbas fictitius  S.chao1 853.32610
    13 Cliona celata complex se.chao1  65.16366
    14        Cliona viridis se.chao1  45.57289
    15      Dysidea fragilis se.chao1  73.82693
    16     Phorbas fictitius se.chao1  57.73494
    

    Next, I want the S variable data split on the period (.) into two variables which I'll call type and var. type contains values S or se and var contains obs or chao1

    mdat <- separate(mdat, S, c("type","var"))
    

    which gives:

                     Group.1 type   var     value
    1  Cliona celata complex    S   obs 499.71430
    2         Cliona viridis    S   obs 285.50000
    3       Dysidea fragilis    S   obs 358.66670
    4      Phorbas fictitius    S   obs 525.91670
    5  Cliona celata complex   se   obs  59.32867
    6         Cliona viridis   se   obs  51.68736
    7       Dysidea fragilis   se   obs  61.03096
    8      Phorbas fictitius   se   obs  24.66763
    9  Cliona celata complex    S chao1 850.68600
    10        Cliona viridis    S chao1 462.54650
    11      Dysidea fragilis    S chao1 701.74990
    12     Phorbas fictitius    S chao1 853.32610
    13 Cliona celata complex   se chao1  65.16366
    14        Cliona viridis   se chao1  45.57289
    15      Dysidea fragilis   se chao1  73.82693
    16     Phorbas fictitius   se chao1  57.73494
    

    The final step in the data processing is to spread out the currently compact data so that we have columns S and se, which we do with spread() (this is a bit like casting in reshape)

    mdat <- spread(mdat, type, value)
    

    which gives us

    mdat
    
    > mdat
                    Group.1   var        S       se
    1 Cliona celata complex chao1 850.6860 65.16366
    2 Cliona celata complex   obs 499.7143 59.32867
    3        Cliona viridis chao1 462.5465 45.57289
    4        Cliona viridis   obs 285.5000 51.68736
    5      Dysidea fragilis chao1 701.7499 73.82693
    6      Dysidea fragilis   obs 358.6667 61.03096
    7     Phorbas fictitius chao1 853.3261 57.73494
    8     Phorbas fictitius   obs 525.9167 24.66763
    

    Now with that done, we can plot

    ggplot(mdat, aes(x = Group.1, y = S, fill = var)) +
        geom_bar(position = "dodge", stat = "identity") +
        geom_errorbar(mapping = aes(ymax = S + se, ymin = S - se),
                      position = position_dodge(width=0.9), width = 0.25)
    

    You only need one call to geom_errorbar() as it has aesthetics ymax and ymin which can be set at the same time.

    This gives produces

    enter image description here