我使用了以下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 ~ .)
+ theme(panel.background = theme_blank())
生产
我想将 facet 标签更改为更短的标签(例如Hosp 1
,Hosp 2
...)因为现在看起来太长了局促(增加图表的高度不是一个选项,它会占用文档中太多的空间)。我查看了facet_grid帮助页面,但无法弄清楚如何。
答案 0 :(得分:259)
这是一个避免编辑数据的解决方案:
假设您的地图由数据框的group
部分构成,其中包含级别control, test1, test2
,然后创建一个以这些值命名的列表:
hospital_names <- list(
'Hospital#1'="Some Hospital",
'Hospital#2'="Another Hospital",
'Hospital#3'="Hospital Number 3",
'Hospital#4'="The Other Hospital"
)
然后创建一个'贴标机'功能,并将其推入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列表,返回列表值(正确的名称)。
请注意,这仅适用于只有一个分面变量的情况。如果您有两个方面,那么您的贴标机功能需要为每个方面返回不同的名称向量。您可以使用以下内容执行此操作:
plot_labeller <- function(variable,value){
if (variable=='facet1') {
return(facet1_names[value])
} else {
return(facet2_names[value])
}
}
其中facet1_names
和facet2_names
是由构面索引名称('Hostpital#1'等)索引的预定义名称列表。
编辑:如果您传递标签程序不知道的变量/值组合,则上述方法将失败。您可以为未知变量添加故障保护,如下所示:
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))
}
}
根据how to change strip.text labels in ggplot with facet and margin=TRUE
改编的答案 编辑:警告:如果您使用此方法通过字符列进行分面,则可能是标签不正确。请参阅最近版本的ggplot2中修复的this bug report。。
答案 1 :(得分:181)
这是另一个解决方案,它符合@ naught101给出的另一个解决方案,但更简单,也不会对最新版本的ggplot2发出警告。
基本上,您首先要创建一个命名的字符向量
ExceptionLogger
然后你将它用作贴标机,只需将@naught101给出的代码的最后一行修改为
hospital_names <- c(
`Hospital#1` = "Some Hospital",
`Hospital#2` = "Another Hospital",
`Hospital#3` = "Hospital Number 3",
`Hospital#4` = "The Other Hospital"
)
希望这有帮助。
答案 2 :(得分:110)
使用以下内容更改基础因子级别名称:
# 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 ~ .)
答案 3 :(得分:23)
以下是我使用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()
的调用 - 这是我在一段时间内遇到的问题。
这种方法的灵感来自帮助页面Coerce to labeller function上的最后一个示例。
答案 4 :(得分:22)
如果您有两个方面hospital
和room
但想重命名一个方面,则可以使用:
facet_grid( hospital ~ room, labeller = labeller(hospital = as_labeller(hospital_names)))
使用基于矢量的方法重命名两个方面(如naught101的答案),你可以这样做:
facet_grid( hospital ~ room, labeller = labeller(hospital = as_labeller(hospital_names),
room = as_labeller(room_names)))
答案 5 :(得分:8)
请注意,如果ggplot显示的因子少于变量实际包含的因素,则此解决方案将无法正常工作(如果您进行了子集化,可能会发生这种情况):
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)
一个简单的解决方案(除了在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)
答案 6 :(得分:8)
此解决方案与@domi的解决方案非常接近,但旨在通过获取前4个字母和最后一个数字来缩短名称。
library(ggplot2)
# simulate some data
xy <- data.frame(hospital = rep(paste("Hospital #", 1:3, sep = ""), each = 30),
value = rnorm(90))
shortener <- function(string) {
abb <- substr(string, start = 1, stop = 4) # fetch only first 4 strings
num <- gsub("^.*(\\d{1})$", "\\1", string) # using regular expression, fetch last number
out <- paste(abb, num) # put everything together
out
}
ggplot(xy, aes(x = value)) +
theme_bw() +
geom_histogram() +
facet_grid(hospital ~ ., labeller = labeller(hospital = shortener))
答案 7 :(得分:6)
简单的解决方案(来自here):
p <- ggplot(mtcars, aes(disp, drat)) + geom_point()
# Example (old labels)
p + facet_wrap(~am)
to_string <- as_labeller(c(`0` = "Zero", `1` = "One"))
# Example (New labels)
p + facet_wrap(~am, labeller = to_string)
答案 8 :(得分:5)
facet_wrap
和facet_grid
都接受来自ifelse
的输入作为参数。因此,如果用于分面的变量是合乎逻辑的,那么解决方案非常简单:
facet_wrap(~ifelse(variable, "Label if true", "Label if false"))
如果变量包含更多类别,则ifelse
语句必须为nested。
作为副作用,这也允许在ggplot
电话中创建分组。
答案 9 :(得分:3)
我认为所有其他解决方案对此非常有帮助,但还有另一种方法。
我假设:
dplyr
软件包,该软件包具有方便的mutate
命令,并且您的数据集名为survey
。
调查%&gt;% mutate(Hosp1 = Hospital1,Hosp2 = Hospital2,........)
此命令可帮助您重命名列,但保留所有其他列。
然后做同样的facet_wrap
,你现在很好。
答案 10 :(得分:3)
以variable, value
作为参数的labeller函数定义对我不起作用。另外,如果要使用表达式,则需要使用lapply,不能简单地使用arr[val]
,因为该函数的参数是data.frame。
此代码确实有效:
libary(latex2exp)
library(ggplot2)
arr <- list('virginica'=TeX("x_1"), "versicolor"=TeX("x_2"), "setosa"=TeX("x_3"))
mylabel <- function(val) { return(lapply(val, function(x) arr[x])) }
ggplot(iris, aes(x=Sepal.Length, y=Sepal.Width)) + geom_line() + facet_wrap(~Species, labeller=mylabel)
答案 11 :(得分:3)
由于我尚未被评论,因此我将其单独发布为Vince's answer和son520804's answer的附录。归功于他们。
Son520804:
使用虹膜数据:
我认为:
您已经安装了dplyr软件包,该软件包具有便捷的mutate命令,并且 您的数据集名为调查。survey %>% mutate(Hosp1 = Hospital1, Hosp2 = Hospital2,........)
此命令可帮助您重命名列,但保留所有其他列。 然后执行相同的facet_wrap,您现在就好了。
使用Vince的鸢尾花示例和son520804的部分代码,我使用mutate函数完成了此操作,并且在不接触原始数据集的情况下实现了简单的解决方案。 诀窍是创建一个替代名称向量,并在管道内部使用mutate()来临时更正构面名称:
i <- iris
levels(i$Species)
[1] "setosa" "versicolor" "virginica"
new_names <- c(
rep("Bristle-pointed iris", 50),
rep("Poison flag iris",50),
rep("Virginia iris", 50))
i %>% mutate(Species=new_names) %>%
ggplot(aes(Petal.Length))+
stat_bin()+
facet_grid(Species ~ .)
在此示例中,您可以看到i $ Species的级别被临时更改为new_names向量中包含的相应公用名。包含
的行mutate(Species=new_names) %>%
可以很容易地删除以显示原始名称。
警告提示:如果未正确设置new_name向量,则很容易在名称中引入错误。使用单独的函数替换变量字符串可能会更清洁。请记住,可能需要以不同的方式重复new_name向量,以匹配原始数据集的顺序。请仔细检查两次,以确保正确实现。
答案 12 :(得分:3)
通过解析数学符号,上标,下标,括号/括号等来添加类似于@domi的解决方案。
library(tidyverse)
theme_set(theme_bw(base_size = 18))
### create separate name vectors
# run `demo(plotmath)` for more examples of mathematical annotation in R
am_names <- c(
`0` = "delta^{15}*N-NO[3]^-{}",
`1` = "sqrt(x,y)"
)
# use `scriptstyle` to reduce the size of the parentheses &
# `bgroup` to make adding `)` possible
cyl_names <- c(
`4` = 'scriptstyle(bgroup("", a, ")"))~T~-~5*"%"',
`6` = 'scriptstyle(bgroup("", b, ")"))~T~+~10~degree*C',
`8` = 'scriptstyle(bgroup("", c, ")"))~T~+~30*"%"'
)
ggplot(mtcars, aes(wt, mpg)) +
geom_jitter() +
facet_grid(am ~ cyl,
labeller = labeller(am = as_labeller(am_names, label_parsed),
cyl = as_labeller(cyl_names, label_parsed))
) +
geom_text(x = 4, y = 25, size = 4, nudge_y = 1,
parse = TRUE, check_overlap = TRUE,
label = as.character(expression(paste("Log"["10"], bgroup("(", frac("x", "y"), ")")))))
### OR create new variables then assign labels directly
# reverse facet orders just for fun
mtcars <- mtcars %>%
mutate(am2 = factor(am, labels = am_names),
cyl2 = factor(cyl, labels = rev(cyl_names), levels = rev(attr(cyl_names, "names")))
)
ggplot(mtcars, aes(wt, mpg)) +
geom_jitter() +
facet_grid(am2 ~ cyl2,
labeller = label_parsed) +
annotate("text", x = 4, y = 30, size = 5,
parse = TRUE,
label = as.character(expression(paste("speed [", m * s^{-1}, "]"))))
由reprex package(v0.2.1.9000)于2019-03-30创建
答案 13 :(得分:2)
我有另一种方法可以在不改变基础数据的情况下实现相同的目标:
$project
我上面所做的是更改原始数据框中因子的标签,这是与原始代码相比的唯一区别。
答案 14 :(得分:2)
只是扩大了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))
}
}
您需要做的是创建一个名为name-to-name mapping的列表
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)
或者,您可以为要拥有的每个标签更改创建专用功能。
答案 15 :(得分:2)
在不修改基础数据的情况下进行更改的最简便方法是:
1)使用as_labeller
函数创建对象为每个默认值添加反勾标记:
hum.names <- as_labeller(c(`50` = "RH% 50", `60` = "RH% 60",`70` = "RH% 70", `80` = "RH% 80",`90` = "RH% 90", `100` = "RH% 100")) #Necesarry to put RH% into the facet labels
2)我们添加到GGplot中:
ggplot(dataframe, aes(x=Temperature.C,y=fit))+geom_line()+ facet_wrap(~Humidity.RH., nrow=2,labeller=hum.names)
答案 16 :(得分:1)
您是否尝试更改Hospital
向量的具体级别?
levels(survey$hospital)[levels(survey$hospital) == "Hospital #1"] <- "Hosp 1"
levels(survey$hospital)[levels(survey$hospital) == "Hospital #2"] <- "Hosp 2"
levels(survey$hospital)[levels(survey$hospital) == "Hospital #3"] <- "Hosp 3"
答案 17 :(得分:1)
这对我有用。
定义一个因素:
hospitals.factor<- factor( c("H0","H1","H2") )
并在ggplot()
中使用:
facet_grid( hospitals.factor[hospital] ~ . )
答案 18 :(得分:0)
我觉得我应该对此做出补充,因为花了我很长时间才能完成这项工作:
在以下情况下,此答案适合您
:reflectScrolledClipView
)
我基本上将标签放在命名的矢量中,因此标签不会混淆或切换。 bquote
表达式可能更简单,但这至少有效(非常欢迎改进)。请注意`(反引号)以保护构面因子。
labeller
答案 19 :(得分:0)
经过一段时间的努力,我发现我们可以结合使用fct_relevel()
中的fct_recode()
和forcats
来更改构面的顺序以及固定构面标签。我不确定它是否受设计支持,但是可以正常工作!查看下面的图:
library(tidyverse)
before <- mpg %>%
ggplot(aes(displ, hwy)) +
geom_point() +
facet_wrap(~class)
before
after <- mpg %>%
ggplot(aes(displ, hwy)) +
geom_point() +
facet_wrap(
vars(
# Change factor level name
fct_recode(class, "motorbike" = "2seater") %>%
# Change factor level order
fct_relevel("compact")
)
)
after
由reprex package(v0.3.0)于2020-02-16创建
答案 20 :(得分:0)
来自 mishabalyasin 的单衬 :
vcB
看到它在行动
facet_grid(.~vs, labeller = purrr::partial(label_both, sep = " #"))
由 reprex package (v2.0.0) 于 2021 年 7 月 9 日创建