使用R进行分面标签化

5

我正在尝试使用分面图绘制数据子集。它是2列x4行的图表。第一列的值在120到150之间,第二列的值在180到250之间,并且变量在数据文件中被分配为“较小”或“较大”。我遇到了一个问题,就是如何将特定标签(“120 <= 希腊字母(alpha) <= 150”、“180 <= 希腊字母(alpha) <= 250”)添加到列变量(“较小”,“较大”)中。我尝试这样做:

require(graphics)
library(ggplot2)
hp <- ggplot2(data) + ....
xlow <- paste("120 <", expression(alpha), " < 150") 
xhi <- paste("180 <", expression(alpha), " < 250")
mf_labeller <- function(var, value){
  value <- as.character(value)
  if (var=="regime") {
  value[value=="Lesser"] <- xlow
  value[value=="Greater"]  <- xhi
}
  return(value) 
}
(hp %+% data) + facet_grid(param~regime,  scales="free", labeller=mf_labeller)

我遇到了一个错误:"Error in value == "Greater" : comparison is not allowed for expressions"。我尝试过强制转换数据,但是没有成功。如果我按任何方式进行标记:

data2 <- transform(data, regime = factor(regime, levels=c("Lesser", "Greater"), labels=c(expression(paste("120 <", alpha," < 150")), expression("180 < alpha < 250"))))

我得到了整个表达式的原文,但没有得到所需的图形。我可能漏掉了一些东西。 非常感谢任何帮助! 提前致谢。

我的样本摘录如下:

regime,param,line,XX,Var,sner
Lesser,Rise,VII,AA,4.968624,0.1275248
Lesser,Rise,VII,BB,3.719405,0.08470305
Lesser,Rise,VII,CC,7.608773,0.177848
Lesser,Rise,VII,DD,9.874395,0.1367159
Lesser,Text,VII,AA,4.968624,0.1275248
Lesser,Text,VII,BB,3.719405,0.08470305
Lesser,Text,VII,CC,7.608773,0.177848
Lesser,Text,VII,DD,9.874395,0.1367159
Lesser,Chant,VII,AA,0.1771826,0.186758
Lesser,Chant,VII,BB,0.3611497,0.5484656
Lesser,Chant,VII,CC,0.7719002,0.8864444
Lesser,Chant,VIII,DD,1.829022,0.2639881
Greater,Rise,VII,AA,4.968624,0.1275248
Greater,Rise,VII,BB,3.719405,0.08470305
Greater,Rise,VII,CC,7.608773,0.177848
Greater,Rise,VII,DD,9.874395,0.1367159
Greater,Text,VII,AA,4.968624,0.1275248
Greater,Text,VII,BB,3.719405,0.08470305
Greater,Text,VII,CC,7.608773,0.177848
Greater,Text,VII,DD,9.874395,0.1367159
Greater,Chant,VII,AA,0.1771826,0.186758
Greater,Chant,VII,BB,0.3611497,0.5484656
Greater,Chant,VII,CC,0.7719002,0.8864444
Greater,Chant,VIII,DD,1.829022,0.2639881

我使用的代码是:我之前在帖子中写错了表达式,但我在代码中使用了正确的表达式。

x <- read.table("sample.csv", header=T, sep=',')
require(graphics)
library(ggplot2)
ppi <- 300
png("figure.png", width=6*ppi, height=6*ppi, res=ppi)
hp <- ggplot(data=x,aes(x=XX, y=Var, colour=line, group = line)) + geom_errorbar(aes(ymin=Var-sner, ymax=Var+sner, colour=line), width=.3) + geom_line(aes(ymax=Var+sner), size=0.7) + geom_point(aes(ymax=Var+sner), shape=21, size=2,fill="white") + theme_bw() + theme(axis.text.x = element_text(angle=90,vjust=0.25), panel.grid.minor=element_blank(), panel.grid.major=element_blank(), panel.background =element_blank(), legend.position="none" ) + scale_colour_hue(l=40) 
xlow <- expression(paste("120 <",alpha," < 150"))
xhi <- expression(paste("180 <", alpha," < 250"))
.. earlier code block as alternative here...
data2 <- transform(x, regime = factor(regime, levels=c("Lesser", "Greater"), labels=c( bquote(120<.(alpha)~phantom()<150), bquote(180<.(alpha)~phantom()<250) )
(hp %+% data2) + facet_grid(param~regime,  scales="free", labeller=label_bquote)

我之前也尝试使用 mf_labeller..

提前感谢您。

3个回答

6
您需要的是用于 plotmath 表达式的表单。
expression(120 <= alpha~phantom() <= 150)
expression(180 <= alpha~phantom() <= 250)

您可以通过直接或间接的方式获得这种技术

parse(text="120 <= alpha~phantom() <= 150")
parse(text="180 <= alpha~phantom() <= 250")

最简单的方法是将因子的级别设置为字符串,并使用label_parsed函数。
使用mtcars数据进行模拟,因为您没有提供可重现的示例:
dat <- mtcars   
dat$regime <- factor(dat$am)
levels(dat$regime) <- list("120 <= alpha~phantom() <= 150" = "0",
                           "180 <= alpha~phantom() <= 250" = "1")

ggplot(aes(x=wt, y=mpg), data=dat) +
  geom_point() +
  facet_grid(cyl ~ regime, labeller=label_parsed)

输入图像说明

如果您真的想使用自己的标签,而不想更改基础数据的因子水平,您也可以这样做。从具有“Lesser”和“Greater”级别的模拟数据开始:

dat <- mtcars   
dat$regime <- factor(dat$am, levels=c(0,1), labels=c("Lesser", "Greater"))

然后标签函数和ggplot代码如下:
mf_labeller <- function(var, value){
  value <- as.character(value)
  if (var=="regime") {
    value[value=="Lesser"] <- "120 <= alpha~phantom() <= 150"
    value[value=="Greater"]  <- "180 <= alpha~phantom() <= 250"
    value <- lapply(value, function(x) parse(text=x))
  }
  return(value) 
}

ggplot(aes(x=wt, y=mpg), data=dat) +
  geom_point() +
  facet_grid(cyl ~ regime, labeller=mf_labeller)

图形看起来一样。


0

我们没有您的数据进行测试(也没有您使用的代码),但是之前使用格子图绘制的经验告诉我,可能需要使用bquotesapplyas.expression的组合。请尝试:

..., labels=c( bquote(120<.(alpha)~phantom()<150), bquote(180<.(alpha)~phantom()<250) )

在代码的第一部分中,我认为你不应该在paste内使用expression,而是先构建标签,然后再构建表达式向量。
如果你变得绝望了,可以先构建图形,然后强制标签成为不同的东西。如何使用网格编辑ggplot2对象以添加数学表达式到facet标签?

谢谢您的回复。但是在我的情况下,这似乎也不起作用。虽然代码可以运行,但没有生成任何输出图。 - user1818565
叹气。当然没有输出。你没有提供任何代码或数据。你会注意到,我希望Brian Diggs使用了phantom()策略来使plotmath工作。 - IRTFM

0

我没有一个确切的答案,但是希望这会有所帮助。我的解决方案在使用两个小于号时会报错,但只使用一个时却可以运行,这似乎是错误的行为。

(编辑,请查看下面的Brian Diggs评论或者以上的答案,以了解为什么这不是错误。)

可用的示例数据,注意我将一个小于号替换为加号:

twolabs  <- c("120<alpha+150","150<alpha+250")
df<- data.frame(x=rnorm(mean=4,40),
   y=rnorm(mean=4,40),
   labs=sample(twolabs,40,replace=T))

这个图表效果非常好。

ggplot(df,aes(x=x,y=y))+geom_point()+facet_grid(.~labs,labeller=label_parsed)

然而,带有两个小于号的数据会抛出错误:
twolabs  <- c("120<alpha<150","150<alpha<250")
df2<- data.frame(x=rnorm(mean=4,40),
   y=rnorm(mean=4,40),
   labs=sample(twolabs,40,replace=T))

> ggplot(df2,aes(x=x,y=y))+geom_point()+facet_grid(.~labs,labeller=label_parsed)
Error in parse(text = x) : <text>:1:10: unexpected '<'
1: 120<alpha<

通过使用label_parsed,我认为我们最终会调用gridDevices :: plotmath,如果值得的话。有人可以进一步吗?

1
< 是一个二元运算符,每个运算符都需要有自己的左右两侧(即使在 plotmath 之外,a<b<c 也不是有效的 R 表达式)。phantom() 可以提供一个缺失的侧面,但不占用任何空间或打印任何内容;请参见其他答案。 - Brian Diggs
那很有道理。谢谢! - MattBagg

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