使用unit.pmax
作为gtable中宽度/高度的默认比较,证明比我希望的更难;经过几个小时的搔痒,我把它缩小到这种情况:
library(grid)
w <- list(unit(1,"null"), unit(1,"null"))
class(w) <- c("unit.list", "unit")
h <- unit(1, "in")
gl1 <- grid.layout(1, 2, widths = w, heights = h,
respect = TRUE)
grid.newpage()
grid.show.layout(gl1) # fine
w2 <- w
w2[[1]] <- unit.pmax(unit(1,"null"), unit(1,"null"))
gl2 <- grid.layout(1, 2, widths = w2, heights = h,
respect = FALSE)
grid.newpage()
grid.show.layout(gl2)# fine
gl3 <- grid.layout(1, 2, widths = w2, heights = h,
respect = TRUE)
grid.newpage()
grid.show.layout(gl3)
## Error in grid.Call.graphics(L_setviewport, vp, TRUE) :
## non-finite location and/or size for viewport
所以unit.pmax(unit(1,"null"), unit(1,"null"))
和respect = TRUE
的组合让网格抱怨。如果您想知道,ggplot2会出现facet_grid
和theme(aspect.ratio = ...)
的情况。
我可以模糊地说明unit.pmax()
在尝试使用respect
参数之前应该简化空单位,但我真的不知道这一切意味着什么。但在实践中,它阻止我改进gtable的cbind / rbind。
任何解决方法?
修改:我不知道如何使用ggplot2
提供最小示例,而不是安装my fork并运行
ggplot(data.frame(x=1:8, y=1:8, f=gl(2,4)), aes(x, y)) +
geom_point() +
facet_grid(f~.) +
theme(aspect.ratio=3)
# Error in grid.Call.graphics(L_setviewport, vp, TRUE) :
# non-finite location and/or size for viewport
所以unit.pmax()
在这种情况下失败,而当前比较方法compare.unit(,,pmax)
在其他情况下失败,例如,
p1 = qplot(1, 1); p2 = qplot(1,1)
cbind(ggplotGrob(p1), ggplotGrob(p2), size="max")
# Error in mmm < each : comparison of these types is not implemented
答案 0 :(得分:3)
它不是最佳的,但如果所有其他方法都失败了,您可以重写unit.pmax
以使其按照您的意愿行事。
以下函数的行为与unit.pmax()
类似,只是当它被要求查找两个或更多单位对象的最大值时,全部以"null"
为单位,它返回它们的值&#34;最大&#34;一,而不是max(x,y,...)
形式的表达。 (有关示例,请参阅下面的第二个代码块。)
unit.pmax2 <-
function (...)
{
select.i <- function(unit, i) {
unit[i, top = FALSE]
}
x <- list(...)
numargs <- length(x)
if (numargs == 0L)
stop("no arguments where at least one expected")
maxlength <- 0L
for (i in seq_len(numargs)) if (length(x[[i]]) > maxlength)
maxlength <- length(x[[i]])
## result <- max(unit.list.from.list(lapply(x, select.i, 1L)))
UL <- grid:::unit.list.from.list(lapply(x, select.i, 1L)) ##
result <- if(all(sapply(UL, attr, "unit")=="null")) { ##
UL[which.max(UL)]} else {max(UL)} ##
if (maxlength > 1L)
for (i in 2L:maxlength) {
## result <- unit.c(result, max(unit.list.from.list(lapply(x,
## select.i, i))))
UL <- grid:::unit.list.from.list(lapply(x, select.i, i)) ##
temp <- if(all(sapply(UL, attr, "unit")=="null")) { ##
UL[which.max(UL)]} else {max(UL)} ##
result <- unit.c(result, temp) ##
}
result
}
要查看unit.pmax()
和unit.pmax2()
之间的区别,请比较:
A <- list(unit(1,"null"), unit(1,"null"), unit(1,"null"))
B <- list(unit(1,"null"), unit(4,"null"), unit(1,"null"))
C <- list(unit(1,"null"), unit(2,"null"), unit(1,"inch"))
class(A) <- class(B) <- class(C) <- c("unit.list", "unit")
unit.pmax(A, B, C)
# [1] max(1null, 1null, 1null) max(1null, 4null, 2null) max(1null, 1null, 1inch)
unit.pmax2(A, B, C)
# [1] 1null 4null max(1null, 1null, 1inch)
测试它表明它有效。 (请注意,您还需要将w2[[1]] <- ...
替换为w2[1] <- ...
以避免在respect = TRUE
时投诉。)
library(grid)
w2 <- list(unit(1,"null"), unit(1,"null"))
class(w2) <- c("unit.list", "unit")
h <- unit(1, "in")
w2[1] <- unit.pmax2(unit(1,"null"), unit(1,"null"))
## w2[[1]] <- unit.pmax(unit(1,"null"), unit(1,"null")) ## For comparison
gl3 <- grid.layout(1, 2, widths = w2, heights = h,
respect = TRUE)
grid.newpage()
grid.show.layout(gl3)
答案 1 :(得分:3)
Paul Murrell在R-devel @r65845中的修正似乎解决了这个问题。不幸的是,这意味着gtable
的更新必须至少等到下一个R版本(可能更长,因为ggplot2开发通常采用保守的方法来支持旧版本)。