From ffaedd3c3ff5cada49f8da07ed97ff1029a48c85 Mon Sep 17 00:00:00 2001 From: Thomas Lin Pedersen Date: Fri, 12 Nov 2021 10:35:31 +0100 Subject: [PATCH 1/2] follow tidyverse recycling rules --- NEWS.md | 3 +++ R/geom-.r | 2 +- R/layer.r | 3 ++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/NEWS.md b/NEWS.md index 5163888679..b92410a8d4 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,8 @@ # ggplot2 (development version) +* Aesthetics of length 1 are now recycled to 0 if the length of the data is 0 + (@thomasp85, #4588) + * Setting `stroke` to `NA` in `geom_point()` will no longer impair the sizing of the points (@thomasp85, #4624) diff --git a/R/geom-.r b/R/geom-.r index e513769c03..8265d6cd4c 100644 --- a/R/geom-.r +++ b/R/geom-.r @@ -208,7 +208,7 @@ NULL .stroke <- 96 / 25.4 check_aesthetics <- function(x, n) { - ns <- vapply(x, length, numeric(1)) + ns <- vapply(x, length, integer(1)) good <- ns == 1L | ns == n if (all(good)) { diff --git a/R/layer.r b/R/layer.r index 197d32549d..dcb66f92bf 100644 --- a/R/layer.r +++ b/R/layer.r @@ -264,7 +264,8 @@ Layer <- ggproto("Layer", NULL, if (length(evaled) == 0) { n <- 0 } else { - n <- max(vapply(evaled, length, integer(1))) + aes_n <- vapply(evaled, length, integer(1)) + n <- if (min(aes_n) == 0) 0L else max(aes_n) } } check_aesthetics(evaled, n) From ecb0ae027e5191c723cfdc729c35c1b7dddf9dc7 Mon Sep 17 00:00:00 2001 From: Thomas Lin Pedersen Date: Tue, 16 Nov 2021 15:27:30 +0100 Subject: [PATCH 2/2] add tests for recycling to 0 --- tests/testthat/test-aes-setting.r | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/testthat/test-aes-setting.r b/tests/testthat/test-aes-setting.r index baa6a12077..4c3e055ea8 100644 --- a/tests/testthat/test-aes-setting.r +++ b/tests/testthat/test-aes-setting.r @@ -13,6 +13,17 @@ test_that("aesthetic parameters match length of data", { set_colours(rep("red", 5)) }) +test_that("Length 1 aesthetics are recycled to 0", { + p <- ggplot(data.frame(x = numeric(), y = numeric())) + + geom_point(aes(x, y, colour = "red")) + + expect_silent(plot(p)) + + data <- layer_data(p) + + expect_equal(nrow(data), 0) +}) + test_that("legend filters out aesthetics not of length 1", { df <- data_frame(x = 1:5, y = 1:5) p <- ggplot(df, aes(x, y, colour = factor(x))) +