我使用了以下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帮助页面,但不知道如何操作。


当前回答

这个解决方案非常接近于@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))

其他回答

我有另一种方法可以在不改变底层数据的情况下实现相同的目标:

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())

我上面所做的是改变原始数据帧中因子的标签,这是与原始代码相比的唯一不同之处。

注意,这个解决方案不会很好地工作,如果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)

我现在解决这个问题的方法是使用dplyr::case_when在facet_grid或facet_wrap函数中生成一个标签器。这是@lillemets提出的解决方案的扩展

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(case_when(hospital == "Hospital #1" ~ "Hosp1",
                         hospital == "Hospital #2" ~ "Hosp2") ~ .)
  + theme(panel.background = theme_blank())

如果您有第二个facet标签要更改,那么只需在facet_grid中的~的另一侧使用相同的方法即可

添加另一个类似于@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包于2019-03-30创建(v0.2.1.9000)

由于我还不被允许评论帖子,所以我单独发布了这篇文章,作为Vince和son520804的答案的补充。功劳归于他们。

Son520804: 使用虹膜数据: 我认为: 您已经安装了dplyr包,其中有方便的mutate命令 您的数据集名为survey。 调查%>%突变(Hosp1 = Hospital1, Hosp2 = Hospital2,........) 此命令帮助您重命名列,但保留所有其他列。 然后执行同样的facet_wrap,现在就没问题了。

使用Vince的虹膜示例和son520804的部分代码,我使用mutate函数做到了这一点,并在不接触原始数据集的情况下实现了一个简单的解决方案。 诀窍是创建一个替代名称向量,并在管道中使用mutate()临时更正facet名称:

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向量可能需要以不同的方式重复,以匹配原始数据集的顺序。请再三检查这是否正确实现。