Как изменить метки фасетов? - PullRequest
201 голосов
/ 13 августа 2010

Я использовал следующую команду 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())

для производства

alt text

Я бы хотел изменить метки facet на более короткие (например, Hosp 1, Hosp 2 ...), потому что они слишком длинные и выглядят тесными (увеличивая высоту графика не вариант, это заняло бы слишком много места в документе). Я посмотрел на страницу справки facet_grid , но не могу понять, как.

Ответы [ 17 ]

264 голосов
/ 24 августа 2012

Вот решение, позволяющее избежать редактирования ваших данных:

Скажем, ваш график огранен частью 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"
)

Затем создайте функцию 'labeller' и вставьте ее в ваш вызов 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))
  }
}

Ответ адаптирован из как изменить метки strip.text в ggplot с фасетом и полем = TRUE


edit: WARNING : если вы используете этот метод для фасетки столбца символ , возможно, вы получаете неправильные метки См. этот отчет об ошибке . , исправленный в последних версиях ggplot2.

186 голосов
/ 15 января 2016

Вот еще одно решение, которое соответствует духу @naught101, но более простое и не выдает предупреждение о последней версии ggplot2.

По сути, сначала вы создаете именованный вектор символов

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

Надеюсь, это поможет.

111 голосов
/ 13 августа 2010

Измените имена базовых уровней факторов на что-то вроде:

# 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 ~ .)
23 голосов
/ 20 марта 2017

Вот как я это сделал с facet_grid(yfacet~xfacet), используя ggplot2, версия 2.2.1:

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() - с этим я боролся некоторое время.

Этот подход основан на последнем примере на странице справки Приведение к функции labeller .

22 голосов
/ 12 июня 2016

Если у вас есть два аспекта 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)))
8 голосов
/ 23 сентября 2018

Это решение очень близко к тому, что имеет @domi, но оно предназначено для сокращения имени путем извлечения первых 4 букв и последнего номера.*

8 голосов
/ 11 июня 2013

Обратите внимание, что это решение не будет работать хорошо в случае, если 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)
5 голосов
/ 08 ноября 2017

И facet_wrap, и facet_grid также принимают ввод от ifelse в качестве аргумента.Поэтому, если переменная, используемая для огранки, логична, решение очень простое:

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

Если переменная имеет больше категорий, оператор ifelse должен быть вложенным .

В качестве побочного эффекта это также позволяет создавать группы в рамках вызова ggplot.

4 голосов
/ 26 февраля 2019

Самый простой способ изменить БЕЗ изменения основных данных:

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)
3 голосов
/ 31 марта 2019

Добавление другого решения, похожего на @ domi's, с синтаксическим анализом математических символов, верхнего индекса, нижнего индекса, скобок / скобок, .etc.

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}, "]"))))

Создано в 2019-03-30 пакетом Представить (v0.2.1.9000)

...