diff --git a/NEWS.md b/NEWS.md index d31e6b4a45..583017fc33 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,7 @@ # ggplot2 (development version) +* `position_dodge(preserve = "single")` now handles multi-row geoms better, + such as `geom_violin()` (@teunbrand based on @clauswilke's work, #2801). * `position_jitterdodge()` now dodges by `group` (@teunbrand, #3656) * The `arrow.fill` parameter is now applied to more line-based functions: `geom_path()`, `geom_line()`, `geom_step()` `geom_function()`, line diff --git a/R/position-dodge.R b/R/position-dodge.R index 17bd607324..c2d0dc1eca 100644 --- a/R/position-dodge.R +++ b/R/position-dodge.R @@ -111,9 +111,9 @@ PositionDodge <- ggproto("PositionDodge", Position, if (identical(self$preserve, "total")) { n <- NULL } else { - panels <- unname(split(data, data$PANEL)) - ns <- vapply(panels, function(panel) max(table(panel$xmin)), double(1)) - n <- max(ns) + n <- vec_unique(data[c("group", "PANEL", "xmin")]) + n <- vec_group_id(n[c("PANEL", "xmin")]) + n <- max(tabulate(n, attr(n, "n"))) } list(