The hardware and bandwidth for this mirror is donated by METANET, the Webhosting and Full Service-Cloud Provider.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]metanet.ch.

Using ggerror

This vignette demonstrates the geom API on symmetric, asymmetric, and one-sided errors. For the package motivation see the README; for stat_error() summaries and sign_aware errors see vignette("use-cases").

Setup

We use airquality — Daily air quality measurements in New York, May to September 1973.

This dataset has 153 rows and 6 columns: four continuous measurements, plus Month and Day.

data("airquality"); airq <- airquality

# It wouldn't be an R workflow without minimal data cleaning...
day_in_month <- function(day_in_month, month, year) {
  days_abbr <- format(as.Date(sprintf("%d-%02d-%02d", year, month, day_in_month)), "%a")
  factor(days_abbr, levels = c("Mon","Tue","Wed","Thu","Fri","Sat","Sun"), ordered = TRUE)

}
airq$Day <- day_in_month(airq$Day, airq$Month, 1973)
airq$Month <- factor(airq$Month, labels = month.abb[5:9])


# summary table, grouped by month with Temp's means and standard deviation 
aq_monthly_avg <- data.frame(
  Month = unique(airq$Month),
  Temp = tapply(airq$Temp, airq$Month, mean),
  sd_temp_monthly   = tapply(airq$Temp, airq$Month, sd)
)

p <- ggplot(aq_monthly_avg, aes(Temp, Month))

Simple and defaults

A single error aesthetic is enough — ggerror infers orientation from the data (here: numeric x axis, discrete y axis) and picks geom_errorbar as the default base geom.


p + 
  geom_error(aes(error = sd_temp_monthly),
             width = 0.4) +
  labs(title = "p + geom_error(aes(error = sd_temp_monthly))",
       caption = "p <- ggplot(aq_monthly_avg, aes(Temp, Month))"
       )

Same data, pinned geom_error_pointrange() wrapper:

p +
  geom_error_pointrange(aes(error = sd_temp_monthly),
                        size = 0.8,
                        shape = "x") +
  labs(title = "p + geom_error_pointrange(aes(error = sd_temp_monthly))")

Same data, swapped via the error_geom argument:

p +
  geom_error(aes(error = sd_temp_monthly),
             error_geom = "linerange") +
  labs(title = "geom_error(error_geom = \"linerange\")")

💡 Tip: Because error_geom is just an argument, you can iterate over it functionally:

purrr::map(c("errorbar", "linerange", "crossbar", "pointrange"),
           ~ p + geom_error(aes(error = sd_temp_monthly), error_geom = .x))

Asymmetric errors

error_neg and error_pos extend in opposite directions regardless of orientation. They’re useful when the dispersion measure on each side carries different meaning.

may_week <- subset(airq[1:7,], Month == 'May')

may_summary <- data.frame(
  Day = may_week$Day,
  Temp = may_week$Temp,
  dist2min = may_week$Temp - min(may_week$Temp, na.rm = TRUE),
  dist2max = max(may_week$Temp, na.rm = TRUE) - may_week$Temp
) # Each Temp point now has its distance from the minimum Temp in the
  # dataset, and its distance from the maximum Temp in the dataset.

:::


ggplot(may_summary, aes(x = Temp, y = Day)) +
  geom_error(aes(error_neg =  dist2min,
                 error_pos = dist2max),
             error_geom = "pointrange",
             color_neg = "steelblue",
             color_pos = "firebrick",
             linewidth  = 1
             ) +
  labs(title = "geom_error(error_neg = dist2min, error_pos = dist2max)")

Deciding what counts as the negative or the positive error is up to your discretion.

Per-side styling extends to color, fill, linewidth, linetype, alpha, and width. Pass either the side-specific form (color_neg, width_pos) or the shared form (color, width).

ggplot(may_summary, aes(Temp, Day)) +
  geom_error(aes(error_neg = dist2min,
                 error_pos = dist2max),
             error_geom = "crossbar",
             fill_neg = "#d97757", fill_pos = "#ffaa66",
             width_neg = 0.3,     width_pos = 0.6) +
  labs(title = "crossbar with per-side fills + widths")

One-sided bars

Sometimes we care mostly about errors towards one side, and dismiss the other as uninteresting. For example, how each observation falls below a threshold. Set the unused side to NA and ggerror suppresses the cap and stem on that side automatically.

ggplot(may_summary, aes(Temp, Day)) +
  geom_error(aes(error_neg = dist2min, error_pos = NA),
             color = "steelblue",
             linewidth = 1,
             linetype = 9) +
  geom_point(size = 1.5) +
  labs(title = "geom_error(aes(error_neg=dist2min, error_pos = NA))")

Remember: The errors are simply a magnitude. They don’t even have to be treated as errors, like in the last couple of examples, where they are treated as distances from some arbitrary value (in this one-sided example: the distance of each temperature from the minimum temperature that was measured).

Passing 0 instead of NA works, but is discouraged, for several reasons: 1. NA is more explicit than 0. 2. Since 0 is treated as a value, it won’t automatically cap out the undesired side of the error bars, for example.

See vignette("use-cases") for more advanced options.

Extending ggerror

If you know of, or need, a new error geom, please open an issue on the GitHub repository. My first motivation was to simplify the heck out of the error geoms, reducing the aesthetics to a single error aesthetic. The rest (asymmetric, one-sided, etc) are just niceties that I added along the way.

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.