grid.layout不喜欢尊重和复合单位

使用unit.pmax作为unit.pmax中宽度/高度的默认比较比我希望的要难得多; 经过几个小时的头部划伤,我缩小了这种情况:

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 with facet_gridtheme(aspect.ratio = ...)

我可以隐约unit.pmax()在尝试使用respect参数之前, unit.pmax()应该简化null单位,但我并不真正知道这一切意味着什么。 但实际上,它阻止了我改进gtable的cbind / rbind。

任何解决方法?

编辑:我不知道如何提供一个最小的例子与ggplot2 ,除了安装我的叉子和运行

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

这不是最优的,但如果其他所有的都失败了,你可以重写unit.pmax来使它做你想做的事情。

下面的函数就像unit.pmax()一样unit.pmax()除了每当要求查找两个或更多个单位对象的最大值时,所有都以"null"单位,它返回它们的值“最大”,而不是表达式形式为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)


Paul Murrell在R-devel @ r65845的修复似乎解决了这个问题。 不幸的是,这意味着gtable的更新至少要等到下一个R版本发布(可能要更长一些,因为ggplot2 dev通常采用保守的方式来支持旧版本)。

链接地址: http://www.djcxy.com/p/79465.html

上一篇: grid.layout doesn't like respect and compound units

下一篇: LD+Hydra link discovery