Reputation: 303
I'm trying to make a faceted plot from a dataframe showing how one variable changes as a function of other variable. Each variable has an error associated with it. Here's a subset of the data I have; an ID column, the variables (SiO2 to FeO) and the errors associated with the variables (*_2stdev):
df<-structure(list(ID = structure(c(3L, 4L, 6L, 1L, 2L, 10L), .Label = c("P466-an1", "P466-an2", "P468-an1", "P468-an2", "P469-an1", "P470-an1", "P471-an1", "P472-an1", "P473-an1", "P474-an1", "P475-an1", "P475-an2", "P476-an1", "P476-an2", "P477-an1", "P478-an1", "P479-an1", "P480-an1"), class = "factor"),
SiO2 = c(54.5147, 56.2223, 52.8499, 52.0293, 53.4221, 52.9802),
TiO2 = c(0.5928, 0.5792, 0.5771, 1.1373, 1.0962, 1.1535),
Al2O3 = c(17.5404, 18.1921, 19.4737, 15.7752, 16.455, 16.4117),
FeO = c(6.2115, 5.8676, 5.4874, 4.5952, 4.4242, 4.109),
SiO2_2stdev = c(1.5232, 2.3578, 0.6374, 1.3331, 0.6535, 0.6977),
TiO2_2stdev = c(0.0638, 0.0637, 0.0357, 0.1024, 0.0422, 0.0282),
Al2O3_2stdev = c(0.4519, 0.4572, 0.2044, 0.6378, 0.6546, 0.0624),
FeO_2stdev = c(0.426, 0.3973, 0.1145, 0.1992, 0.1106, 0.0427)),
.Names = c("ID", "SiO2", "TiO2", "Al2O3", "FeO", "SiO2_2stdev", "TiO2_2stdev", "Al2O3_2stdev", "FeO_2stdev"),
row.names = c(NA, 6L), class = "data.frame")
Using the following code:
library(reshape2)
library(ggplot2)
m.df<-melt(df, id=c('ID','FeO'))
p<-ggplot(subset(m.df, variable %in% c('SiO2','TiO2','Al2O3')),aes(x=value, y=FeO))+
geom_point()+
facet_wrap(~ variable, ncol=1, scales="free_x")+
theme_bw()
p
I get this plot:
I would like to add the errorbars (vertical and horizontal) to this, but I don't know how to do this on a faceted plot.
Using geom_errorbar
and geom_errorbarh
, I've been able to plot these for individual plots from the unmelted dataframe. I suppose I could make all the plots with a loop, but I don't know how to add the errorbars with this method. Further, I'd like to see all the plots at once.
Thanks for reading this and any help is greatly appreciated! -R
edit
As per aosmith's comment, I've added FeO_2stdev
to the ID variables in melt
. I'm now able to produce a plot with the correc vertical errorbars. So now I have trouble understanding how I can get geom_errorbarh
to plot the correct errorbars on for each plot.
Below is the updated code I'm using, with the resulting plot.
library(reshape2)
library(ggplot2)
m.df<-melt(df, id=c('ID','FeO', 'FeO_2stdev'))
m.df$y.min<-m.df$FeO-m.df$FeO_2stdev
m.df$y.max<-m.df$FeO+m.df$FeO_2stdev
p<-ggplot(subset(m.df, variable %in% c('SiO2','TiO2','Al2O3')), aes(x=value, y=FeO))+
geom_point()+
facet_wrap(~ variable, ncol=1, scales="free_x")+
theme_bw()+
geom_errorbar(aes(ymin=y.min, ymax=y.max))
p
Upvotes: 0
Views: 132
Reputation: 36114
Having a dataset with one column of values and one column of 2 standard deviations will help with the horizontal error bars. This is essentially a data manipulation problem. There are many ways to achieve such a thing. I'm using tidyr with dplyr.
For example, if you start with m.df
immediately after melting, you could
separate
and then mutate
with if_else
.spread
the dataset back into a wide format, with one column for the values and one for the 2 standard deviations. You could also use dcast
from reshape2 if you are already familiar with it.library(dplyr) library(tidyr)
m.df %>%
separate(variable, c("variable", "metric")) %>%
mutate(metric = if_else(is.na(metric), "value", metric)) %>%
spread(metric, value)
ID FeO FeO_2stdev variable 2stdev value
1 P466-an1 4.5952 0.1992 Al2O3 0.6378 15.7752
2 P466-an1 4.5952 0.1992 SiO2 1.3331 52.0293
3 P466-an1 4.5952 0.1992 TiO2 0.1024 1.1373
4 P466-an2 4.4242 0.1106 Al2O3 0.6546 16.4550
5 P466-an2 4.4242 0.1106 SiO2 0.6535 53.4221
...
Here's the whole process using gather
from tidyr instead of melt
for the same results:
df2 = df %>%
gather(key, value, -ID, -contains("FeO")) %>%
separate(key, c("variable", "metric")) %>%
mutate(metric = if_else(is.na(metric), "value", metric)) %>%
spread(metric, value)
Now the horizontal error bars can be added to your plot using value
and 2stdev
. Note that the column name 2stdev
isn't syntactically correct so I use backticks around the variable name.
ggplot(df2, aes(x=value, y=FeO))+
geom_point()+
facet_wrap(~ variable, ncol=1, scales="free_x")+
theme_bw() +
geom_errorbar(aes(ymin = FeO - FeO_2stdev, ymax = FeO + FeO_2stdev)) +
geom_errorbarh(aes(xmin = value - `2stdev`, xmax = value + `2stdev`))
Upvotes: 1