From e75707cd363e0d3e97a52f544b3540b42b8d6371 Mon Sep 17 00:00:00 2001 From: Teun van den Brand Date: Mon, 3 Nov 2025 10:20:06 +0100 Subject: [PATCH 1/5] Fix for formula/call labels --- R/layer.R | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/R/layer.R b/R/layer.R index d4396aeb4e..2b98cf84b9 100644 --- a/R/layer.R +++ b/R/layer.R @@ -974,7 +974,10 @@ normalise_label <- function(label) { if (obj_is_list(label)) { # Ensure that each element in the list has length 1 label[lengths(label) == 0] <- "" - label <- lapply(label, `[`, 1) + # Don't mess with call/formula + if (!is.call(label[[1]])) { + label <- lapply(label, `[`, 1) + } } if (is.expression(label)) { # Classed expressions, when converted to lists, retain their class. From 01d7c46045bdd9b5f100f6391e0e84eaac736148 Mon Sep 17 00:00:00 2001 From: Teun van den Brand Date: Mon, 3 Nov 2025 10:52:13 +0100 Subject: [PATCH 2/5] mirror #6690 for position aesthetics --- R/position-.R | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/R/position-.R b/R/position-.R index 845b095862..4f3008c725 100644 --- a/R/position-.R +++ b/R/position-.R @@ -102,6 +102,10 @@ Position <- ggproto( #' A data frame with completed layer data use_defaults = function(self, data, params = list()) { + if (empty(data)) { + return(data) + } + aes <- self$aesthetics() defaults <- self$default_aes @@ -113,6 +117,13 @@ Position <- ggproto( return(data) } + empty_aes <- names(params)[lengths(params) == 0] + if (length(empty_aes) > 0) { + # The Geom$use_defaults method will already warn about this, we just need + # to ignore this here. + params <- params[setdiff(names(params), empty_aes)] + } + new <- compact(lapply(defaults, eval_tidy, data = data)) new[names(params)] <- params check_aesthetics(new, nrow(data)) From 0ec4e7e1a0002018f8ebe0bf87473cbde931afcb Mon Sep 17 00:00:00 2001 From: Teun van den Brand Date: Mon, 3 Nov 2025 12:20:42 +0100 Subject: [PATCH 3/5] preserve attributes of list-labels --- R/layer.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/layer.R b/R/layer.R index 2b98cf84b9..272ee5dace 100644 --- a/R/layer.R +++ b/R/layer.R @@ -976,7 +976,7 @@ normalise_label <- function(label) { label[lengths(label) == 0] <- "" # Don't mess with call/formula if (!is.call(label[[1]])) { - label <- lapply(label, `[`, 1) + label[] <- lapply(label, `[`, 1) } } if (is.expression(label)) { From a502f6c6650d0ea66e13544d5f3632c8679e445d Mon Sep 17 00:00:00 2001 From: Teun van den Brand Date: Mon, 3 Nov 2025 12:21:06 +0100 Subject: [PATCH 4/5] fallback for `StatAlign$finish_layer` --- R/stat-align.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/stat-align.R b/R/stat-align.R index 7278773cf3..c0807382c7 100644 --- a/R/stat-align.R +++ b/R/stat-align.R @@ -77,7 +77,7 @@ StatAlign <- ggproto( finish_layer = function(data, params) { # Silently remove out-of-bounds padding vertices - var <- flipped_names(params$flipped_aes)$x + var <- flipped_names(params$flipped_aes %||% FALSE)$x remove <- is.na(data[[var]]) & (data$align_padding %||% FALSE) vec_slice(data, !remove) } From 0e7f18ae25cb3f7f508be4dd9fa8b96342998139 Mon Sep 17 00:00:00 2001 From: Teun van den Brand Date: Mon, 3 Nov 2025 14:14:42 +0100 Subject: [PATCH 5/5] be more thorough with truncating label lists --- R/layer.R | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/R/layer.R b/R/layer.R index 272ee5dace..179f519441 100644 --- a/R/layer.R +++ b/R/layer.R @@ -974,10 +974,8 @@ normalise_label <- function(label) { if (obj_is_list(label)) { # Ensure that each element in the list has length 1 label[lengths(label) == 0] <- "" - # Don't mess with call/formula - if (!is.call(label[[1]])) { - label[] <- lapply(label, `[`, 1) - } + truncate <- !vapply(label, is.call, logical(1)) # Don't mess with call/formula + label[truncate] <- lapply(label[truncate], `[`, 1) } if (is.expression(label)) { # Classed expressions, when converted to lists, retain their class.