Reputation: 3568
I would like to add an if else statement within the mapping statement within geom_errorbar()
that removes the lower error bar if it fulfills a certain criteria. See the following toy dataset and graph
df <- data.frame(change = rep(c("increased", "reduced", "same"), 2),
group = rep(c("0", "1"), each = 3),
freq = c(0, 17, 21, 1, 27, 9),
perc = c(0, 44.73, 55.26, 2.70, 72.97, 24.32),
se = c(NaN, 12.06, 10.85, 16.22, 8.54, 14.30))
polytPlot <- ggplot(dfT, aes(y = perc, x = change, fill = Group)) +
geom_bar(stat = "identity", position = "dodge") +
scale_y_continuous(breaks=pretty) +
ylab("% of group total") +
xlab("Change") +
geom_errorbar(aes(ymin = ifelse(perc-se < 0, 0, perc-se), ymax = perc+se), position = position_dodge(.9), width = .1)
polytPlot
Note that the ifelse()
statement in the ymin
argument of geom_errorbar
in the above example does work, reducing the lower error bar to zero, but it still displays the horizontal portion of the error bar. How do I suppress this, so only the upper error-bar appears? I tried entering NULL
instead of 0 in my conditional ifelse()
statement but got an error message. Perhaps a conditional argument to width =
?
Upvotes: 4
Views: 1213
Reputation: 17810
One option is to remove the horizontal crossbars altogether:
ggplot(df, aes(y = perc, x = change, fill = group)) +
geom_bar(stat = "summary", position = "dodge") +
scale_y_continuous(breaks=pretty) +
ylab("% of group total") +
xlab("Change") +
geom_linerange(aes(ymin = ifelse(perc-se < 0, 0, perc-se), ymax = perc+se), position = position_dodge(.9))
If you really want the crossbars, however, you can draw them separately using geom_segment()
:
ggplot(df, aes(y = perc, x = change, fill = group)) +
geom_bar(stat = "summary", position = "dodge") +
scale_y_continuous(breaks=pretty, limits = c(0, 85)) +
ylab("% of group total") +
xlab("Change") +
geom_linerange(aes(ymin = ifelse(perc-se < 0, 0, perc-se), ymax = perc+se), position = position_dodge(.9)) +
geom_segment(aes(x = as.numeric(change) + .45*(as.numeric(group)-1.5) - .05,
xend = as.numeric(change) + .45*(as.numeric(group)-1.5) + .05,
y = perc + se, yend = perc + se)) +
geom_segment(aes(x = as.numeric(change) + .45*(as.numeric(group)-1.5) - .05,
xend = as.numeric(change) + .45*(as.numeric(group)-1.5) + .05,
y = perc - se, yend = perc - se))
Note that the missing segment is removed by the limits
statement I added to scale_y_continuous()
.
Upvotes: 5