diff --git a/R/facet-.r b/R/facet-.r index 27a1e1a9cb..43356ffd64 100644 --- a/R/facet-.r +++ b/R/facet-.r @@ -486,6 +486,17 @@ check_layout <- function(x) { cli::cli_abort("Facet layout has a bad format. It must contain columns {.col PANEL}, {.col SCALE_X}, and {.col SCALE_Y}") } +check_facet_vars <- function(..., name) { + vars_names <- c(...) + reserved_names <- c("PANEL", "ROW", "COL", "SCALE_X", "SCALE_Y") + problems <- intersect(vars_names, reserved_names) + if (length(problems) != 0) { + cli::cli_abort(c( + "{.val {problems}} {?is/are} not {?an/} allowed name{?/s} for faceting variables", + "i" = "Change the name of your data columns to not be {.or {.str {reserved_names}}}" + ), call = call2(name)) + } +} #' Get the maximal width/length of a list of grobs #' diff --git a/R/facet-grid-.r b/R/facet-grid-.r index 894fbb9c75..02f30ef515 100644 --- a/R/facet-grid-.r +++ b/R/facet-grid-.r @@ -196,16 +196,18 @@ grid_as_facets_list <- function(rows, cols) { FacetGrid <- ggproto("FacetGrid", Facet, shrink = TRUE, - compute_layout = function(data, params) { + compute_layout = function(self, data, params) { rows <- params$rows cols <- params$cols + check_facet_vars(names(rows), names(cols), name = snake_class(self)) + dups <- intersect(names(rows), names(cols)) if (length(dups) > 0) { cli::cli_abort(c( "Faceting variables can only appear in {.arg rows} or {.arg cols}, not both.\n", "i" = "Duplicated variables: {.val {dups}}" - )) + ), call = call2(snake_class(self))) } base_rows <- combine_vars(data, params$plot_env, rows, drop = params$drop) diff --git a/R/facet-wrap.r b/R/facet-wrap.r index 70ca5dc89a..58c65bc55f 100644 --- a/R/facet-wrap.r +++ b/R/facet-wrap.r @@ -147,6 +147,8 @@ FacetWrap <- ggproto("FacetWrap", Facet, return(layout_null()) } + check_facet_vars(names(vars), name = snake_class(self)) + base <- combine_vars(data, params$plot_env, vars, drop = params$drop) id <- id(base, drop = TRUE) diff --git a/tests/testthat/_snaps/facet-layout.md b/tests/testthat/_snaps/facet-layout.md index 3bc7aa60bb..797deb33a1 100644 --- a/tests/testthat/_snaps/facet-layout.md +++ b/tests/testthat/_snaps/facet-layout.md @@ -39,3 +39,18 @@ Free scales cannot be mixed with a fixed aspect ratio +# facet_wrap and facet_grid throws errors when using reserved words + + "ROW" is not an allowed name for faceting variables + i Change the name of your data columns to not be "PANEL", "ROW", "COL", "SCALE_X", or "SCALE_Y" + +--- + + "ROW" and "PANEL" are not allowed names for faceting variables + i Change the name of your data columns to not be "PANEL", "ROW", "COL", "SCALE_X", or "SCALE_Y" + +--- + + "ROW" is not an allowed name for faceting variables + i Change the name of your data columns to not be "PANEL", "ROW", "COL", "SCALE_X", or "SCALE_Y" + diff --git a/tests/testthat/test-facet-layout.r b/tests/testthat/test-facet-layout.r index 8a256ac6b4..7f56f20488 100644 --- a/tests/testthat/test-facet-layout.r +++ b/tests/testthat/test-facet-layout.r @@ -187,3 +187,15 @@ test_that("facet_grid throws errors at bad layout specs", { theme(aspect.ratio = 1) expect_snapshot_error(ggplotGrob(p)) }) + +test_that("facet_wrap and facet_grid throws errors when using reserved words", { + mtcars2 <- mtcars + mtcars2$PANEL <- mtcars2$cyl + mtcars2$ROW <- mtcars2$gear + + p <- ggplot(mtcars2) + + geom_point(aes(mpg, disp)) + expect_snapshot_error(ggplotGrob(p + facet_grid(ROW ~ gear))) + expect_snapshot_error(ggplotGrob(p + facet_grid(ROW ~ PANEL))) + expect_snapshot_error(ggplotGrob(p + facet_wrap(~ROW))) +})