Ernie
Ernie

Reputation: 1153

Grouped ggplot2 barplot with missing error bars

I am trying to figure out how to have error bars plotted for only some members of a group plot. For example, I have a data set defined as:

 new_frame <- data.frame(Parms = c("CAGR", "CAGR", "CAGR", 
                                   "CAGR", "CAGR", "DD", "DD",
                                   "DD","DD","DD"),
                         Values = c(28, 27.4, 26.9, 24.6, 27.9, 
                                    18.7, 19.2, 18.5, 19.2, 19.1),
                         Rebal = c(18, 19, 20, 21, 22,
                                   18, 19, 20, 21, 22),
                         sd = c(2.8, 2.3, 1.9, 2.9, 2.1, 0,0,0,0,0))

which gives for new_frame:

   Parms Values Rebal  sd
1   CAGR   28.0    18 2.8
2   CAGR   27.4    19 2.3
3   CAGR   26.9    20 1.9
4   CAGR   24.6    21 2.9
5   CAGR   27.9    22 2.1
6     DD   18.7    18 0.0
7     DD   19.2    19 0.0
8     DD   18.5    20 0.0
9     DD   19.2    21 0.0
10    DD   19.1    22 0.0

My ggplot2 statement is:

library(ggplot2)
ggplot(new_frame, aes(x=Rebal, y=Values, fill=Parms)) +
  geom_bar(position="dodge", stat="identity") + 
  geom_errorbar(aes(ymin=Values - sd, ymax=Values + sd),
  position=position_dodge(0.9), width=0.2) +
  ggtitle("           Variation With Rebalance Period”)

and the plot is:

Example of missing error bars

My question is how to avoid plotting the null error ticks for the green bars. Putting 0’s into new_frame for the sd values for DD still draws the ticks, and putting NAs into those positions throws a ggplot error.

Upvotes: 2

Views: 1231

Answers (2)

Gregor Thomas
Gregor Thomas

Reputation: 145775

Set the 0 values to NA:

# in the data
new_frame$sd[new_frame$sd == 0] = NA

# or inline 
aes(ymin = Values - ifelse(sd == 0, NA, sd), ymax = Values + ifelse(sd == 0, NA, sd))

This will throw a warning by default. You can disable the warning by adding the argument na.rm = TRUE to geom_errorbar layer:

geom_errorbar(
    aes(ymin = Values - sd, ymax = Values + sd),
    na.rm = T,
    position = position_dodge(0.9),
    width = 0.2
  )

I appreciate the clever color = sd == 0 approach, but this is a more general way to do it that doesn't depend on what other aesthetics are in use. (E.g., if you had mapped a color aesthetic for the error bar, then you would need to pick a different aesthetic for that approach to work.)

Upvotes: 1

pogibas
pogibas

Reputation: 28339

You can set geom_errorbar color where value == 0 to NA:

ggplot(new_frame, aes(Rebal, Values, fill = Parms)) +
    geom_bar(position = "dodge", stat = "identity") + 
    geom_errorbar(aes(ymin = Values - sd, ymax = Values + sd,
                      # Is SD 0 (returns logical value)
                      color = sd == 0),
                  position = position_dodge(0.9), width = 0.2) +
    # Set 0 SD color to NA
    scale_color_manual(values = c("black", NA), guide = FALSE)

enter image description here

Upvotes: 2

Related Questions