我注意到 ggplot2geom_text() geom 中有一个意外行为。如果属性 hjustvjust 被指定为字符串,R 将返回强制错误,尽管这些图似乎没有问题。问题出现在我正在开发的 ggplot2-based package 中。为简单起见,我创建了仍然会产生错误的精简示例。

首先,我用 qplot() 试了一下

##qplot version
library(ggplot2)
p <- qplot(cty, hwy,
           label = drv,
           hjust = "right",
           geom  = "text",
           data  = mpg
)

print(p)

我收到了这个错误:
Warning message:
In validDetails.text(x) : NAs introduced by coercion

然后我用 ggplot() 试了一下:
##ggplot version
library(ggplot2)
p <- ggplot(
          aes(x   = cty,
              y   = hwy
          ), data = mpg
)

p <- p + geom_text(
           aes(label = drv),
           hjust     = "right"
)

print(p)

并得到了相同的情节和相同的错误:
Warning message:
In validDetails.text(x) : NAs introduced by coercion

然后我尝试设置 hjust 和 vjust:
library(ggplot2)
p <- ggplot(
          aes(x   = cty,
              y   = hwy
          ), data = mpg
)

p <- p + geom_text(
           aes(label = drv),
           hjust     = "right",
           vjust     = "top"
)

print(p)

使用字符串设置两个参数后,R 返回两个强制错误:
Warning messages:
1: In validDetails.text(x) : NAs introduced by coercion
2: In validDetails.text(x) : NAs introduced by coercion

但是,当参数是数字时,R 不会返回强制错误:
## Using numbers instead of strings
library(ggplot2)
p <- ggplot(
          aes(x   = cty,
              y   = hwy
          ), data = mpg
)

p <- p + geom_text(
           aes(label = drv),
           hjust     = 0,
           vjust     = 0,
           data      = mpg
)

print(p)

我不太确定为什么会发生这种情况,或者这是否很重要,但我没想到。

ggplot2 文档不同意

Hadley's book (p. 196) 表示 hjustvjust可以接受字符串参数:



但是 0.8.9 版本中 geom_text() 的 man 文件说 hjust 和 vjust 是数字,尽管它没有说它们可以
只能是数字:

最佳答案

所以,我不太了解什么代码定义或使用了 hjust/vjust,但是使用 TextMate 的“在项目中查找”(在 ggplot2/R/目录中)进行 hjust,我没有看到任何看起来像它们的行hjust 的定义或实现...只是将它列为有效 aes 的地方以及它被传递的地方。

这让我想去阅读网格......

http://stat.ethz.ch/R-manual/R-patched/library/grid/html/grid.text.html

这让我想了解更多关于 grid.text 是如何定义的

R> grid.text

function (label, x = unit(0.5, "npc"), y = unit(0.5, "npc"),
    just = "centre", hjust = NULL, vjust = NULL, rot = 0, check.overlap = FALSE,
    default.units = "npc", name = NULL, gp = gpar(), draw = TRUE,
    vp = NULL)
{
    tg <- textGrob(label = label, x = x, y = y, just = just,
        hjust = hjust, vjust = vjust, rot = rot, check.overlap = check.overlap,
        default.units = default.units, name = name, gp = gp,
        vp = vp)
    if (draw)
        grid.draw(tg)
    invisible(tg)
}
<environment: namespace:grid>

所以,它是一个 textGrob,并且只是,hjust 和 vjust 只是被传递到它......关闭到 textGrob
R> textGrob
function (label, x = unit(0.5, "npc"), y = unit(0.5, "npc"),
    just = "centre", hjust = NULL, vjust = NULL, rot = 0, check.overlap = FALSE,
    default.units = "npc", name = NULL, gp = gpar(), vp = NULL)
{
    if (!is.unit(x))
        x <- unit(x, default.units)
    if (!is.unit(y))
        y <- unit(y, default.units)
    grob(label = label, x = x, y = y, just = just, hjust = hjust,
        vjust = vjust, rot = rot, check.overlap = check.overlap,
        name = name, gp = gp, vp = vp, cl = "text")
}
<environment: namespace:grid>

所以,这是一个 grob ....... 去 grob ......
R> grob
function (..., name = NULL, gp = NULL, vp = NULL, cl = NULL)
{
    g <- list(..., name = name, gp = gp, vp = vp)
    if (!is.null(cl) && !is.character(cl))
        stop("Invalid 'grob' class")
    class(g) <- c(cl, "grob", "gDesc")
    validGrob(g)
}
<environment: namespace:grid>

没有什么太大的帮助,所以我谷歌

R 网格 hjust vjust

在覆盖 Google 对我的搜索的自动更正后,我发现

http://rwiki.sciviews.org/doku.php?id=tips:graphics-grid:hvjust

回顾哈德利的书,我注意到第 196 页的引用文献实际上并没有提到 hjust 或 vjust……只是理由。

阅读文档
R> ?textGrob

我看到
just     The justification of the text relative to its (x, y) location. If there are two values, the first value specifies horizontal justification and the second value specifies vertical justification. Possible string values are: "left", "right", "centre", "center", "bottom", and "top". For numeric values, 0 means left alignment and 1 means right alignment.
hjust    A numeric vector specifying horizontal justification. If specified, overrides the just setting.
vjust    A numeric vector specifying vertical justification. If specified, overrides the just setting.

所以,这是我的想法。
  • just 参数可以是字符串或数字
  • hjust 和 vjust 只是数字,可以覆盖
  • 如果您尝试为它们使用字符串,它可能“有效”,但会抛出警告

  • 因此,让我们看一下 grid.text 演示代码,特别是 draw.text 函数,它们使用字符串值似乎成功地做到了这一点:
    grid.newpage()
    x <- stats::runif(20)
    y <- stats::runif(20)
    rot <- stats::runif(20, 0, 360)
    grid.text("SOMETHING NICE AND BIG", x=x, y=y, rot=rot,
              gp=gpar(fontsize=20, col="grey"))
    grid.text("SOMETHING NICE AND BIG", x=x, y=y, rot=rot,
              gp=gpar(fontsize=20), check=TRUE)
    grid.newpage()
    
    draw.text <- function(just, i, j) {
      grid.text("ABCD", x=x[j], y=y[i], just=just)
      grid.text(deparse(substitute(just)), x=x[j], y=y[i] + unit(2, "lines"),
                gp=gpar(col="grey", fontsize=8))
    }
    
    x <- unit(1:4/5, "npc")
    y <- unit(1:4/5, "npc")
    grid.grill(h=y, v=x, gp=gpar(col="grey"))
    draw.text(c("bottom"), 1, 1)
    draw.text(c("left", "bottom"), 2, 1)
    draw.text(c("right", "bottom"), 3, 1)
    draw.text(c("centre", "bottom"), 4, 1)
    draw.text(c("centre"), 1, 2)
    draw.text(c("left", "centre"), 2, 2)
    draw.text(c("right", "centre"), 3, 2)
    draw.text(c("centre", "centre"), 4, 2)
    draw.text(c("top"), 1, 3)
    draw.text(c("left", "top"), 2, 3)
    draw.text(c("right", "top"), 3, 3)
    draw.text(c("centre", "top"), 4, 3)
    draw.text(c(), 1, 4)
    draw.text(c("left"), 2, 4)
    draw.text(c("right"), 3, 4)
    draw.text(c("centre"), 4, 4)
    

    现在注意如果我更改 draw.text 以使用 hjust 和 vjust AS STRINGS 的区别
    grid.newpage()
    x <- stats::runif(20)
    y <- stats::runif(20)
    rot <- stats::runif(20, 0, 360)
    grid.text("SOMETHING NICE AND BIG", x=x, y=y, rot=rot,
              gp=gpar(fontsize=20, col="grey"))
    grid.text("SOMETHING NICE AND BIG", x=x, y=y, rot=rot,
              gp=gpar(fontsize=20), check=TRUE)
    grid.newpage()
    
    draw.text <- function(just, i, j) {
      grid.text("ABCD", x=x[j], y=y[i], hjust=just[1], vjust=just[2])
      grid.text(deparse(substitute(just)), x=x[j], y=y[i] + unit(2, "lines"),
                gp=gpar(col="grey", fontsize=8))
    }
    
    x <- unit(1:4/5, "npc")
    y <- unit(1:4/5, "npc")
    grid.grill(h=y, v=x, gp=gpar(col="grey"))
    draw.text(c("bottom"), 1, 1)
    draw.text(c("left", "bottom"), 2, 1)
    draw.text(c("right", "bottom"), 3, 1)
    draw.text(c("centre", "bottom"), 4, 1)
    draw.text(c("centre"), 1, 2)
    draw.text(c("left", "centre"), 2, 2)
    draw.text(c("right", "centre"), 3, 2)
    draw.text(c("centre", "centre"), 4, 2)
    draw.text(c("top"), 1, 3)
    draw.text(c("left", "top"), 2, 3)
    draw.text(c("right", "top"), 3, 3)
    draw.text(c("centre", "top"), 4, 3)
    draw.text(c(), 1, 4)
    draw.text(c("left"), 2, 4)
    draw.text(c("right"), 3, 4)
    draw.text(c("centre"), 4, 4)
    

    长话短说:我认为当你使用 hjust 或 vjust 作为字符串时,你违反了文档(它的值应该是数字 0

    关于r - 为什么当 hjust 和 vjust 是字符串时 geom_text() 会抛出强制错误?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5072841/

    10-12 17:24