diff --git a/R/position-dodge.R b/R/position-dodge.R index b3818cf08c..380e5bcd45 100644 --- a/R/position-dodge.R +++ b/R/position-dodge.R @@ -106,6 +106,11 @@ PositionDodge <- ggproto("PositionDodge", Position, reverse = NULL, setup_params = function(self, data) { flipped_aes <- has_flipped_aes(data, default = self$orientation == "y") + check_required_aesthetics( + if (flipped_aes) "y|ymin" else "x|xmin", + names(data), snake_class(self) + ) + data <- flip_data(data, flipped_aes) if (is.null(data$xmin) && is.null(data$xmax) && is.null(self$width)) { cli::cli_warn(c( @@ -117,8 +122,10 @@ PositionDodge <- ggproto("PositionDodge", Position, if (identical(self$preserve, "total")) { n <- NULL } else { - n <- vec_unique(data[c("group", "PANEL", "xmin")]) - n <- vec_group_id(n[c("PANEL", "xmin")]) + data$xmin <- data$xmin %||% data$x + cols <- intersect(colnames(data), c("group", "PANEL", "xmin")) + n <- vec_unique(data[cols]) + n <- vec_group_id(n[setdiff(cols, "group")]) n <- max(tabulate(n, attr(n, "n"))) } diff --git a/tests/testthat/test-position_dodge.R b/tests/testthat/test-position_dodge.R index 1d7127a239..9107de1d92 100644 --- a/tests/testthat/test-position_dodge.R +++ b/tests/testthat/test-position_dodge.R @@ -37,3 +37,19 @@ test_that("position_dodge() can reverse the dodge order", { ld <- get_layer_data(p + geom_col(position = position_dodge(reverse = FALSE))) expect_equal(ld$label[order(ld$x)], c("A", "A", "B", "B", "C")) }) + +test_that("position_dodge warns about missing required aesthetics", { + + # Bit of a contrived geom to not have a required 'x' aesthetic + GeomDummy <- ggproto(NULL, GeomPoint, required_aes = NULL, optional_aes = "x") + + p <- ggplot(mtcars, aes(cyl, disp, colour = factor(vs))) + + layer( + geom = GeomDummy, + stat = "identity", + position = position_dodge(width = 0.5), + mapping = aes(x = NULL) + ) + + expect_error(ggplot_build(p), "requires the following missing aesthetics") +})