在ggplot的坐标轴标签中使用下标字母

90

我正在尝试找出如何在坐标轴标签中使用下标字母。

dat <- data.frame(x = rnorm(100), y = rnorm(100))
ggplot(dat, aes(x=x,y=y)) +
    geom_point() +
    labs(y=expression(Blah[1]))

dat <- data.frame(x = rnorm(100), y = rnorm(100))
ggplot(dat, aes(x=x,y=y)) +
    geom_point() +
    labs(y=expression(Blah[1d]))

第一个示例可行,因为它只是一个数字,一旦方括号中有字符,它就会失败。Blah[subscript(1d)]基本上是我需要的,但我不知道如何让它允许我在下标中使用字母。我尝试了各种变体,包括paste()

以下示例提供奇怪的行为:

labs(y=expression(Blah[12])) # this works
labs(y=expression(Blah[d])) # this works
labs(y=expression(Blah[d1])) # this works
labs(y=expression(Blah[1d])) # this fails

你有什么想法?


简短版:y=expression(Blah[1*d]) 需要一个非空格的 R 语法运算符,即 * - IRTFM
2个回答

93

最后一个失败的原因是expression的参数会经过R解析器,当它们未通过是否可能是正确的R语法的测试时,就会返回错误。字符串或标记1d不是有效的R标记(或符号)。可以将其分成有效的R标记并使用非空格操作符“连接”,用反引号括起来,或者使用普通引号。我认为这两种方法都比使用paste更好:

 ggplot(dat, aes(x=x,y=y)) +
     geom_point() +
     labs(y=expression(Blah[1*d]))
 ggplot(dat, aes(x=x,y=y)) +
     geom_point() +
     labs(y=expression(Blah["1d"]))

R中的令牌(或“名称”或“符号”)不应以数字开头。因此,您可以通过引用或使用非空格分隔符——*运算符绕过该限制,将1d分开。这样就可以将纯数字文字与合法的R符号或令牌“连接”或“连结”。

要获取未带下标的百分号,只需:

 ggplot(dat, aes(x=x,y=y)) +
    geom_point() +
    labs(y=expression(Blah[1*d]*"%"))

在百分号周围加上括号:

expression(Blah[1*d]*"(%)")

%字符在R解析中具有特殊含义,因为它表示用户定义的中缀运算符的开始。因此,将其用作文字需要加引号。同样的理由要求引号包含"for"和"in",因为它们属于R的"保留字"组。还有其他保留字(但是forin是我经常犯错的)。输入以下内容:

 ?Reserved

另一个“技巧”是在 italic() 中使用引号将数字括起来,以使它们变为斜体。未加引号的数字不会在该函数内部变成斜体。

注意: paste 是一个 plotmath 函数,除了其语义不同于 base::paste 函数外。特别地,它没有 'sep' 参数。因此,你永远无法在打印的参数之间得到一个空格,如果你尝试放入一个非空格项,则所有其他参数之后将出现单个实例,标记为 sep=" "

paste0 不是 plotmath 函数,因此不会被解释,而是将与其未处理的参数出现在括号中。


谢谢DWin,我不知道它被称为令牌。虽然这不是问题的一部分(但在我的答案中),你能否在不使用paste的情况下获得(%)? - nzcoops
1
特别感谢非空格分隔符,我已经寻找它有一段时间了。 - JelenaČuklina
对我来说,一直让人惊讶的是 ?plotmath 页面没有更好地描述其语法要求。它只是说它就像普通的 R 一样,但他们真的应该添加一个小段落来扩展说明。 - IRTFM

16

好的。我发誓我不是为了自己回答这个问题而发布的,尽管我很快就得到了答案(当你提出一个问题时总是这样!)

这就是答案:

ggplot(dat, aes(x=x,y=y)) +
    geom_point() +
    labs(y=expression(Blah[1][d]))

考虑到这个回答可能会在未来帮助到其他人,所以我认为最好还是发布这个回答而不是删除问题。

除了那些琐碎的细节以外,我实际上想要的是expression(paste("Hb", A[1][c]," (%)",sep=""))

为什么paste0()在这里不起作用我无法理解。


9
paste0 不是一个 plotmath 函数。paste 是一个 plotmath 函数,但它的语义与 base::paste 函数不同。特别地,它没有 'sep' 参数。 - IRTFM
在 R 表达式中,您需要引用任何特殊字符,如 % 或保留字,例如 "in"。 - IRTFM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接