From abc70e280bf83c1e8cdbe53ba18fdf145d8dd33c Mon Sep 17 00:00:00 2001 From: Teun van den Brand <49372158+teunbrand@users.noreply.github.com> Date: Thu, 14 Dec 2023 13:21:35 +0100 Subject: [PATCH] `stat_count()` respects uniqueness of `x` (#5520) * instead of removing, `position_stack()` sets incomplete data to missing * adjust test * add test * Add news bullet --- NEWS.md | 3 +++ R/stat-count.R | 3 +-- tests/testthat/test-stat-count.R | 11 +++++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/NEWS.md b/NEWS.md index dbac0a777b..71f471a2fc 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,8 @@ # ggplot2 (development version) +* `stat_count()` treats `x` as unique in the same manner `unique()` does + (#4609). + * `position_stack()` no longer silently removes missing data, which is now handled by the geom instead of position (#3532). diff --git a/R/stat-count.R b/R/stat-count.R index 705e0f4226..81790d7aa1 100644 --- a/R/stat-count.R +++ b/R/stat-count.R @@ -75,8 +75,7 @@ StatCount <- ggproto("StatCount", Stat, x <- data$x weight <- data$weight %||% rep(1, length(x)) - count <- as.numeric(tapply(weight, x, sum, na.rm = TRUE)) - count[is.na(count)] <- 0 + count <- as.vector(rowsum(weight, x, na.rm = TRUE)) bars <- data_frame0( count = count, diff --git a/tests/testthat/test-stat-count.R b/tests/testthat/test-stat-count.R index 827ac9f109..7483becf94 100644 --- a/tests/testthat/test-stat-count.R +++ b/tests/testthat/test-stat-count.R @@ -4,3 +4,14 @@ test_that("stat_count() checks the aesthetics", { p <- ggplot(mtcars) + stat_count(aes(factor(gear), mpg)) expect_snapshot_error(ggplot_build(p)) }) + +test_that("stat_count() respects uniqueness of `x`", { + # For #4609, converting x to factor loses smallest digits, so here we test + # if they are retained + df <- data_frame0(x = c(1, 2, 1, 2) + rep(c(0, 1.01 * .Machine$double.eps), each = 2)) + p <- ggplot(df, aes(x)) + stat_count(position = "identity") + data <- layer_data(p) + + expect_length(vec_unique(df$x), 4) + expect_equal(data$y, rep(1, 4)) +})