Skip to content

Commit 1112f76

Browse files
committed
Fix unit-to-numeric coercion assumptions (#3098)
* More reliable check for "npc" unit * Make sure units are not merged * fix implicit unit->numeric coercion attempts when calculating dimensions for facet_wrap
1 parent 949f724 commit 1112f76

File tree

5 files changed

+44
-19
lines changed

5 files changed

+44
-19
lines changed

R/facet-.r

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -462,18 +462,25 @@ check_layout <- function(x) {
462462
#' Get the maximal width/length of a list of grobs
463463
#'
464464
#' @param grobs A list of grobs
465+
#' @param value_only Should the return value be a simple numeric vector giving
466+
#' the maximum in cm
465467
#'
466-
#' @return The largest value. measured in cm as a unit object
468+
#' @return The largest value. measured in cm as a unit object or a numeric
469+
#' vector depending on `value_only`
467470
#'
468471
#' @keywords internal
469472
#' @export
470-
max_height <- function(grobs) {
471-
unit(max(unlist(lapply(grobs, height_cm))), "cm")
473+
max_height <- function(grobs, value_only = FALSE) {
474+
height <- max(unlist(lapply(grobs, height_cm)))
475+
if (!value_only) height <- unit(height, "cm")
476+
height
472477
}
473478
#' @rdname max_height
474479
#' @export
475-
max_width <- function(grobs) {
476-
unit(max(unlist(lapply(grobs, width_cm))), "cm")
480+
max_width <- function(grobs, value_only = FALSE) {
481+
width <- max(unlist(lapply(grobs, width_cm)))
482+
if (!value_only) width <- unit(width, "cm")
483+
width
477484
}
478485
#' Find panels in a gtable
479486
#'

R/facet-wrap.r

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -281,10 +281,22 @@ FacetWrap <- ggproto("FacetWrap", Facet,
281281
axis_mat_y_left[, -1] <- list(zeroGrob())
282282
axis_mat_y_right[, -ncol] <- list(zeroGrob())
283283
}
284-
axis_height_top <- unit(apply(axis_mat_x_top, 1, max_height), "cm")
285-
axis_height_bottom <- unit(apply(axis_mat_x_bottom, 1, max_height), "cm")
286-
axis_width_left <- unit(apply(axis_mat_y_left, 2, max_width), "cm")
287-
axis_width_right <- unit(apply(axis_mat_y_right, 2, max_width), "cm")
284+
axis_height_top <- unit(
285+
apply(axis_mat_x_top, 1, max_height, value_only = TRUE),
286+
"cm"
287+
)
288+
axis_height_bottom <- unit(
289+
apply(axis_mat_x_bottom, 1, max_height, value_only = TRUE),
290+
"cm"
291+
)
292+
axis_width_left <- unit(
293+
apply(axis_mat_y_left, 2, max_width, value_only = TRUE),
294+
"cm"
295+
)
296+
axis_width_right <- unit(
297+
apply(axis_mat_y_right, 2, max_width, value_only = TRUE),
298+
"cm"
299+
)
288300
# Add back missing axes
289301
if (any(empties)) {
290302
first_row <- which(apply(empties, 1, any))[1] - 1
@@ -330,10 +342,10 @@ FacetWrap <- ggproto("FacetWrap", Facet,
330342
placement <- if (inside) 0 else 1
331343
strip_pad <- axis_height_bottom
332344
}
333-
strip_height <- unit(apply(strip_mat, 1, max_height), "cm")
345+
strip_height <- unit(apply(strip_mat, 1, max_height, value_only = TRUE), "cm")
334346
panel_table <- weave_tables_row(panel_table, strip_mat, placement, strip_height, strip_name, 2, coord$clip)
335347
if (!inside) {
336-
strip_pad[unclass(strip_pad) != 0] <- strip_padding
348+
strip_pad[as.numeric(strip_pad) != 0] <- strip_padding
337349
panel_table <- weave_tables_row(panel_table, row_shift = placement, row_height = strip_pad)
338350
}
339351
} else {
@@ -345,11 +357,11 @@ FacetWrap <- ggproto("FacetWrap", Facet,
345357
placement <- if (inside) 0 else 1
346358
strip_pad <- axis_width_right
347359
}
348-
strip_pad[unclass(strip_pad) != 0] <- strip_padding
349-
strip_width <- unit(apply(strip_mat, 2, max_width), "cm")
360+
strip_pad[as.numeric(strip_pad) != 0] <- strip_padding
361+
strip_width <- unit(apply(strip_mat, 2, max_width, value_only = TRUE), "cm")
350362
panel_table <- weave_tables_col(panel_table, strip_mat, placement, strip_width, strip_name, 2, coord$clip)
351363
if (!inside) {
352-
strip_pad[unclass(strip_pad) != 0] <- strip_padding
364+
strip_pad[as.numeric(strip_pad) != 0] <- strip_padding
353365
panel_table <- weave_tables_col(panel_table, col_shift = placement, col_width = strip_pad)
354366
}
355367
}

R/grob-dotstack.r

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,15 @@ dotstackGrob <- function(
1313
y <- unit(y, default.units)
1414
if (!is.unit(dotdia))
1515
dotdia <- unit(dotdia, default.units)
16-
if (attr(dotdia,"unit") != "npc")
16+
if (!is_npc(dotdia))
1717
warning("Unit type of dotdia should be 'npc'")
1818

1919
grob(x = x, y = y, stackaxis = stackaxis, dotdia = dotdia,
2020
stackposition = stackposition, stackratio = stackratio,
2121
name = name, gp = gp, vp = vp, cl = "dotstackGrob")
2222
}
23+
# Only cross-version reliable way to check the unit of a unit object
24+
is_npc <- function(x) isTRUE(grepl('^[^+^-^\\*]*[^s]npc$', as.character(x)))
2325

2426
#' @export
2527
makeContext.dotstackGrob <- function(x, recording = TRUE) {

R/theme.r

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ add_theme <- function(t1, t2, t2name) {
424424
if (is.null(x) || inherits(x, "element_blank")) {
425425
# If x is NULL or element_blank, then just assign it y
426426
x <- y
427-
} else if (is.null(y) || is.character(y) || is.numeric(y) ||
427+
} else if (is.null(y) || is.character(y) || is.numeric(y) || is.unit(y) ||
428428
is.logical(y) || inherits(y, "element_blank")) {
429429
# If y is NULL, or a string or numeric vector, or is element_blank, just replace x
430430
x <- y

man/max_height.Rd

Lines changed: 7 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)