Question

I have estimates for a pair of outcomes from the same model and I want to show these results using error bars. How can I create a pair of plot that compares estimates of rea in the sample data with all others (rea and sci, rea and mat etc..). In all the plots rea should always appear as a first in the plot and the order of the data should not change.

       library (ggplot2) 
ucl<- c(5.88 , 3.92,  7.0,  3.724,  5.488) 
lcl<-c(1.04 ,  0.04,  2.04, -0.06   , 0.84) 
est<-c(3 , 2,   4,  1.9,    2.8) 
df<-data.frame (cbind(est,ucl, lcl))

df$labels<-c("sci","rea","mat","apt","hor") 

This code creates individual plots, but my need is a pair of plots comparing rea with others.

 ggplot(df, aes(x = labels, y = est,ymin = lcl, ymax = ucl))  +
    geom_point(position=position_dodge() ,size = 2.5) + 
    geom_linerange(position=position_dodge(), size =0.5) +
    geom_hline(aes(yintercept = 1))  
Was it helpful?

Solution 2

You could change your data frame to get desired result.

First, make data frame df2 that contains one line for each level of sci, mat, apt and hor and four lines of rea. Then make column labels as factor with levels in order you need (rea as first, then all other levels). Add column labels2 that contains the same level names as labels except rea and each level is used twice (once for the same level and once for rea).

df2<-rbind(df[-2,],df[rep(2,4),])
df2$labels<-factor(df2$labels,levels=c("rea","sci","mat","apt","hor"))
df2$labels2<-factor(rep(c("sci","mat","apt","hor"),times=2),
                     levels=c("sci","mat","apt","hor")) 
df2
   est   ucl   lcl labels labels2
1  3.0 5.880  1.04    sci     sci
3  4.0 7.000  2.04    mat     mat
4  1.9 3.724 -0.06    apt     apt
5  2.8 5.488  0.84    hor     hor
2  2.0 3.920  0.04    rea     sci
21 2.0 3.920  0.04    rea     mat
22 2.0 3.920  0.04    rea     apt
23 2.0 3.920  0.04    rea     hor

Now use df2 for the plotting of your data - labels are used for x axis but labels2 for the facets. Add scales="free_x" inside facet_wrap() to remove unused levels in each facet.

ggplot(df2,aes(x = labels, y = est,ymin = lcl, ymax = ucl))  +
  geom_point(size = 2.5) + 
  geom_linerange(size =0.5) +
  geom_hline(aes(yintercept = 1)) +
  facet_wrap(~labels2,scales="free_x")

enter image description here

UPDATE

To get all lineranges in one plot add to dataframe df2 (made in example above) column type with two levels - rea and other.

df2$type<-rep(c("other","rea"),each=4)

Then use labels2 as x values and type to set color= or shape=, or just group= for lineranges.

ggplot(df2,aes(x = labels2, y = est,ymin = lcl, ymax = ucl,color=type,shape=type))+
  geom_point(position=position_dodge(width=0.5) ,size = 2.5) + 
  geom_linerange(position=position_dodge(width=0.5), size =0.5) +
  geom_hline(aes(yintercept = 1))  

enter image description here

OTHER TIPS

If I got it correctly, you need facets. It can be like this:

# Additional column for faceting
df$not.rea <- df$labels!="rea"

# Your solution + facet_grid with labeller and free scales/space
ggplot(df, aes(x=labels, y=est, ymin=lcl, ymax=ucl)) +
  geom_point(position=position_dodge(), size=2.5) + 
  geom_linerange(position=position_dodge(), size=0.5) +
  geom_hline(aes(yintercept=1)) +
  facet_grid(~not.rea, scales="free", space="free", 
             labeller=function(var,val) c("rea","other")[val+1])

It produces:

enter image description here

But if you want face-to-face comparison of each estimation to rea, you can subset data.frame which is passed to ggplot2, i.e. for rea vs. mat:

ggplot(df[df$labels %in% c("rea","mat"),], ...) + ...

UPDATE:

In order to produce 4 plots you can use this approach:

# Convert labels to factor - rea should always be first
df$labels <- factor(df$labels, levels=c("rea","sci","mat","apt","hor"))

# Plotting function
one.plot <- function(filter){
  ggplot(df[df$labels %in% c("rea",filter),], aes(x=labels, y=est, ymin=lcl, ymax=ucl)) +
    geom_point(position=position_dodge(), size=2.5) + 
    geom_linerange(position=position_dodge(), size=0.5) +
    geom_hline(aes(yintercept=1)) +
    facet_grid(~labels, scales="free", space="free")
}

# Runner of the batch
sapply(as.character(df$labels[df$labels != "rea"]), function(s) print(one.plot(s)) )

It shows 4 plots. If you want to save them as separate files, you can modify the runner like this:

sapply(as.character(df$labels[df$labels != "rea"]), function(s) ggsave(paste0(s,".png"), one.plot(s)) )

It saves 4 *.png files to working directory.

UPDATE 2:

To produce 4 pairs of errorbars in single plot, you can utilize gridExtra package. It's as easy as:

library(gridExtra)
grid.arrange(one.plot("sci"),
             one.plot("mat"),
             one.plot("apt"),
             one.plot("hor"),
             ncol=2, main="Main Title")

Which produces:

enter image description here

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top