ggplot:如何改变facet标签?

我已经使用了下面的ggplot命令:

ggplot(survey,aes(x=age))+stat_bin(aes(n=nrow(h3),y=..count../n), binwidth=10) +scale_y_continuous(formatter = "percent", breaks=c(0, 0.1, 0.2)) + facet_grid(hospital ~ .) + opts(panel.background = theme_blank()) 

生产

替代文字

但是,我希望将标签标签更改为更短的标签(如Hosp 1,Hosp 2 …),因为它们太长了,看起来很拥挤(增加graphics高度不是一种select,文档中的空间太多)。 我看着facet_grid帮助页面,但无法弄清楚如何。

使用类似于以下的方式更改基础级别的名称:

 # Using the Iris data > i <- iris > levels(i$Species) [1] "setosa" "versicolor" "virginica" > levels(i$Species) <- c("S", "Ve", "Vi") > ggplot(i, aes(Petal.Length)) + stat_bin() + facet_grid(Species ~ .) 

这是一个更好的解决scheme,避免编辑你的数据:

假设你的情节是由你的数据框的一部分组成的,它有一个control, test1, test2级别control, test1, test2 ,然后创build一个由这些值命名的列表:

 hospital_names <- list( 'Hospital#1'="Some Hospital", 'Hospital#2'="Another Hospital", 'Hospital#3'="Hospital Number 3", 'Hospital#4'="The Other Hospital" ) 

然后创build一个“贴标签”function,并将其推入到facet_grid调用中:

 hospital_labeller <- function(variable,value){ return(hospital_names[value]) } ggplot(survey,aes(x=age)) + stat_bin(aes(n=nrow(h3),y=..count../n), binwidth=10) + facet_grid(hospital ~ ., labeller=hospital_labeller) ... 

这使用数据框的级别来索引hospital_names列表,返回列表值(正确的名称)。


请注意,这只适用于你只有一个分面variables。 如果您有两个方面,那么您的标签工具需要为每个方面返回一个不同的名称向量。 你可以用这样的东西做到这一点:

 plot_labeller <- function(variable,value){ if (variable=='facet1') { return(facet1_names[value]) } else { return(facet2_names[value]) } } 

其中facet1_namesfacet2_names是由分面索引名称('Hostpital#1'等)索引的名称的预定义列表。


编辑:如果您传递贴标签不知道的variables/值组合,上述方法失败。 您可以为未知variables添加一个失败保护,如下所示:

 plot_labeller <- function(variable,value){ if (variable=='facet1') { return(facet1_names[value]) } else if (variable=='facet2') { return(facet2_names[value]) } else { return(as.character(value)) } } 

回答如何改变ggplot带有facet和margin = TRUE的strip.text标签


编辑: 警告 :如果您使用此方法来面向字符列,您可能会得到不正确的标签。 看到这个错误报告 。 在最新版本的ggplot2中修复。

这是另外一个解决scheme,它是由@ naught101提供的,但更简单,也不会在最新版本的ggplot2上发出警告。

基本上,你首先创build一个命名的字符向量

 hospital_names <- c( `Hospital#1` = "Some Hospital", `Hospital#2` = "Another Hospital", `Hospital#3` = "Hospital Number 3", `Hospital#4` = "The Other Hospital" ) 

然后你用它作为一个贴标签,只需修改@ naught101给出的代码的最后一行即可

 ... + facet_grid(hospital ~ ., labeller = as_labeller(hospital_names)) 

希望这可以帮助。

如果你有两个方面的hospitalroom但只想重命名一个,你可以使用:

 facet_grid( hospital ~ room, labeller = labeller(hospital = as_labeller(hospital_names))) 

为了使用基于vector的方法重命名两个方面(如naught101的答案),可以这样做:

 facet_grid( hospital ~ room, labeller = labeller(hospital = as_labeller(hospital_names), room = as_labeller(room_names))) 

请注意,如果ggplot显示的variables比variables实际包含的要less(这可能会发生,如果你是例如子集),这个解决scheme将无法正常工作:

  library(ggplot2) labeli <- function(variable, value){ names_li <- list("versicolor"="versi", "virginica"="virg") return(names_li[value]) } dat <- subset(iris,Species!="setosa") ggplot(dat, aes(Petal.Length)) + stat_bin() + facet_grid(Species ~ ., labeller=labeli) 

一个简单的解决scheme(除了在names_li中添加所有未使用的因素,这可能是单调乏味的)是使用droplevels()或者在原始数据集中,或者在labbeler函数中删除未使用的因素,参见:

 labeli2 <- function(variable, value){ value <- droplevels(value) names_li <- list("versicolor"="versi", "virginica"="virg") return(names_li[value]) } dat <- subset(iris,Species!="setosa") ggplot(dat, aes(Petal.Length)) + stat_bin() + facet_grid(Species ~ ., labeller=labeli2) 

下面是我使用ggplot2版本2.2.1与facet_grid(yfacet~xfacet)做的:

 facet_grid( yfacet~xfacet, labeller = labeller( yfacet = c(`0` = "an y label", `1` = "another y label"), xfacet = c(`10` = "an x label", `20` = "another x label) ) ) 

请注意,这不包含对as_labeller()的调用,这是我一段时间as_labeller()

这种方法的灵感来自于帮助页面上的最后一个示例Coerce到贴标签function 。

只是扩大naught101的答案 – 信贷给他

 plot_labeller <- function(variable,value, facetVar1='<name-of-1st-facetting-var>', var1NamesMapping=<pass-list-of-name-mappings-here>, facetVar2='', var2NamesMapping=list() ) { #print (variable) #print (value) if (variable==facetVar1) { value <- as.character(value) return(var1NamesMapping[value]) } else if (variable==facetVar2) { value <- as.character(value) return(var2NamesMapping[value]) } else { return(as.character(value)) } } 

你必须做的是创build一个名称到名称映射的列表

 clusteringDistance_names <- list( '100'="100", '200'="200", '300'="300", '400'="400", '600'="500" ) 

并用新的默认参数重新定义plot_labeller()

 plot_labeller <- function(variable,value, facetVar1='clusteringDistance', var1NamesMapping=clusteringDistance_names, facetVar2='', var1NamesMapping=list() ) 

接着:

 ggplot() + facet_grid(clusteringDistance ~ . , labeller=plot_labeller) 

或者,您可以为每个您想要的标签更改创build专用function。

我有另一种方法来实现相同的目标,而不改变基础数据:

 ggplot(transform(survey, survey = factor(survey, labels = c("Hosp 1", "Hosp 2", "Hosp 3", "Hosp 4"))), aes(x = age)) + stat_bin(aes(n = nrow(h3),y=..count../n), binwidth = 10) + scale_y_continuous(formatter = "percent", breaks = c(0, 0.1, 0.2)) + facet_grid(hospital ~ .) + opts(panel.background = theme_blank()) 

我上面做的是更改原始数据框中的因子的标签,这是与您的原始代码相比唯一的区别。

facet_wrapfacet_grid接受来自ifelseinput作为参数。 所以如果用于分面的variables是合乎逻辑的,那么解决scheme非常简单:

 facet_wrap(~ifelse(variable, "Label if true", "Label if false")) 

如果variables有更多的类别,则ifelse语句需要嵌套 。

作为副作用,这也允许在ggplot调用中创build组。