Wie ändere ich Facettenbeschriftungen?

229

Ich habe den folgenden ggplotBefehl verwendet:

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

produzieren

Alt-Text

Ich möchte die Facettenbeschriftungen jedoch in etwas kürzeres (wie ...) ändern Hosp 1, Hosp 2da sie jetzt zu lang sind und eng aussehen (das Erhöhen der Höhe des Diagramms ist keine Option, es würde zu viel Platz in Anspruch nehmen das Dokument). Ich habe auf die Facet_grid-Hilfeseite geschaut , kann aber nicht herausfinden, wie.

Wishihadabettername
quelle

Antworten:

122

Ändern Sie die Namen der zugrunde liegenden Faktorstufen wie folgt:

# 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 ~ .)
Vince
quelle
12
@wishihadabettername: Um zu vermeiden, dass zugrunde liegende Daten geändert werden, können Sie verwenden: ggplot(transform(iris, Species = c("S", "Ve", "Vi")[as.numeric(Species)]), aes(Petal.Length)) + stat_bin() + facet_grid(Species ~ .)
Arnaud A
1
Verwandte ... Wenn Sie möchten, dass die Bedienfeldbezeichnung ein Ausdruck bquote () ist (z. B. levels(x$measurements) <- c(bquote(Area ~~ (cm^2)), bquote(Length ~~ (cm)))), wird sie nicht im mathematischen Ausdruck angezeigt . Wie würde man Ausdrücke als Facettenbezeichnungen anzeigen?
Brian D
Verwenden Sie die folgende labellerOption, um Ausdrücke in das Facettenetikett aufzunehmen facet_grid: stackoverflow.com/questions/37089052/…
Brian D
285

Hier ist eine Lösung, die das Bearbeiten Ihrer Daten vermeidet:

groupAngenommen, Ihr Plot wird durch den Teil Ihres Datenrahmens mit Ebenen facettiert control, test1, test2, und erstellen Sie dann eine Liste mit den folgenden Werten:

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

Erstellen Sie dann eine Labeller-Funktion und übertragen Sie sie in Ihren facet_grid-Aufruf:

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

Dabei werden die Ebenen des Datenrahmens verwendet, um die Liste der Krankenhausnamen zu indizieren und die Listenwerte (die richtigen Namen) zurückzugeben.


Bitte beachten Sie, dass dies nur funktioniert, wenn Sie nur eine Facettenvariable haben. Wenn Sie zwei Facetten haben, muss Ihre Etikettierfunktion für jede Facette einen anderen Namensvektor zurückgeben. Sie können dies mit etwas tun wie:

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

Wo facet1_namesund facet2_namessind vordefinierte Listen von Namen, die durch die Facettenindexnamen indiziert sind ('Hostpital # 1' usw.).


Bearbeiten: Die obige Methode schlägt fehl, wenn Sie eine Variablen- / Wertekombination übergeben, die der Etikettierer nicht kennt. Sie können eine Ausfallsicherung für unbekannte Variablen wie folgt hinzufügen:

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

Antwort angepasst an das Ändern von strip.text-Beschriftungen in ggplot mit Facette und Rand = TRUE


edit: WARNUNG : Wenn Sie diese Methode verwenden, um eine Zeichenspalte zu facettieren, erhalten Sie möglicherweise falsche Beschriftungen. Siehe diesen Fehlerbericht . in neueren Versionen von ggplot2 behoben.

naught101
quelle
9
Schön, funktioniert aber nicht mit facet_wrap, während die @ Prince-Lösung auch mit facet_wrap funktioniert.
Arnaud A
@ArnaudAmzallag: Richtig, aber wenn jemand Lust hat, etwas Zeit zu spenden, könnte dies in Zukunft der Fall sein .
naught101
Fail-Safe für unbekannte Facettenvariablen hinzugefügt.
Naught101
16
Hinweis: Dies funktioniert in ggplot2 v.2 nicht - die Etikettierfunktion wurde geändert. @mbirons Antwort funktioniert stackoverflow.com/a/34811062/162832
Andreas
Interessant, aber das funktioniert nicht immer, wohingegen das Bearbeiten der Faktoren immer funktioniert.
PatrickT
214

Hier ist eine andere Lösung, die im Geiste der von @ naught101 angegebenen ist, aber einfacher ist und auch keine Warnung auf die neueste Version von ggplot2 wirft.

Grundsätzlich erstellen Sie zunächst einen benannten Zeichenvektor

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

Und dann verwenden Sie es als Etikettierer, indem Sie einfach die letzte Zeile des Codes ändern, der von @ naught101 an angegeben wird

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

Hoffe das hilft.

mbiron
quelle
In welcher Version von ggplot2 befindet sich as_labeller? Ich habe einen Quellcode für das CRAN GitHub-Repository gefunden , aber nach dem Upgrade auf die neueste Version (auf CRAN!) Scheine ich die Funktion nicht zu haben.
n1k31t4
Das ist komisch. Ich habe auch über CRAN aktualisiert. Hier ist die Dokumentation docs.ggplot2.org/dev/as_labeller.html
mbiron
4
Das ist cool. Was passiert, wenn Sie zwei Variablen in Ihrem Facettenraster haben? Wie hospital ~ genderoder so? Gibt es eine Möglichkeit, Etikettierer auf beiden Achsen zu verwenden? Ich kann in den Dokumenten nichts Offensichtliches sehen.
naught101
3
Beachten Sie, wenn Sie mit der Antwort von nichts begonnen haben, funktioniert diese nur mit einem c (), nicht mit einer Liste () .
Thomas88wp
1
Ein großer Teil davon ist, dass dies mit beiden Achsen des Facettengitters funktioniert!
Calum You
29

So habe ich es mit facet_grid(yfacet~xfacet)ggplot2, Version 2.2.1 gemacht:

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

Beachten Sie, dass dies keinen Anruf enthält as_labeller()- etwas, mit dem ich eine Weile zu kämpfen hatte.

Dieser Ansatz ist vom letzten Beispiel auf der Hilfeseite Coerce to Labeller-Funktion inspiriert .

Bovender
quelle
das funktioniert!!! Ich konnte die anderen Lösungen nicht anwenden, da einige der vorgeschlagenen Lösungen in aktuellen ggplot2-Versionen veraltet waren.
Yanes
Sie können diese benannten Vektoren mit setNames() stackoverflow.com/a/22428439/3362993
jsta
23

Wenn Sie zwei Facetten haben hospitalund roomnur eine umbenennen möchten, können Sie Folgendes verwenden:

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

Um zwei Facetten mithilfe des vektorbasierten Ansatzes umzubenennen (wie in der Antwort von naught101), haben Sie folgende Möglichkeiten:

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

Die EINFACHSTE Möglichkeit, Änderungen vorzunehmen, ohne die zugrunde liegenden Daten zu ändern, ist:

1) Erstellen Sie ein Objekt mit der as_labellerFunktion Hinzufügen des hinteren Häkchens für jeden der Standardwerte :

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) Wir fügen dem GGplot hinzu:

ggplot(dataframe, aes(x=Temperature.C,y=fit))+geom_line()+ facet_wrap(~Humidity.RH., nrow=2,labeller=hum.names)
Leinfloyd
quelle
1
Dies ist meiner Meinung nach die eleganteste Methode - sie ist effektiv und funktioniert mit ggplot2 Version 3.0.0.9000
Landak
9

Beachten Sie, dass diese Lösung nicht gut funktioniert, wenn ggplot weniger Faktoren anzeigt, als Ihre Variable tatsächlich enthält (was passieren könnte, wenn Sie beispielsweise eine Teilmenge verwendet hätten):

 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)

Eine einfache Lösung (neben dem Hinzufügen aller nicht verwendeten Faktoren in names_li, was mühsam sein kann) besteht darin, die nicht verwendeten Faktoren mit droplevels () entweder im Originaldatensatz oder in der Labbeler-Funktion zu löschen, siehe:

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)
Matifou
quelle
9

Diese Lösung kommt dem von @domi sehr nahe, soll jedoch den Namen verkürzen, indem die ersten 4 Buchstaben und die letzte Zahl abgerufen werden.

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

Geben Sie hier die Bildbeschreibung ein

Roman Luštrik
quelle
6

Beide facet_wrapund facet_gridakzeptieren auch Eingaben von ifelseals Argument. Wenn die für das Facettieren verwendete Variable logisch ist, ist die Lösung sehr einfach:

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

Wenn die Variable mehr Kategorien hat, muss die ifelseAnweisung verschachtelt werden .

Als Nebeneffekt ermöglicht dies auch die Facettierung der Gruppen innerhalb des ggplotAnrufs.

lillemets
quelle
5

Hinzufügen einer anderen Lösung ähnlich der von @ domi mit dem Parsen von mathematischen Symbolen, hochgestellten, tiefgestellten, Klammern / Klammern usw.

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

Erstellt am 30.03.2019 durch das reprex-Paket (v0.2.1.9000)

Tung
quelle
Siehe auch
Tung
3

Ich denke, alle anderen Lösungen sind wirklich hilfreich, aber es gibt noch einen anderen Weg.

Ich nehme an:

  • Sie haben das dplyrPaket installiert , das den praktischen mutateBefehl hat, und
  • Ihr Datensatz heißt survey .

    Umfrage%>% mutieren (Hosp1 = Krankenhaus1, Hosp2 = Krankenhaus2, ........)

Mit diesem Befehl können Sie Spalten umbenennen, alle anderen Spalten bleiben jedoch erhalten.

Dann mach dasselbe facet_wrap, es geht dir jetzt gut.

son520804
quelle
Entschuldigung, es funktioniert nicht, da es auch den Spalteninhalt ändert
Jens
3

Die Definition der Etikettierfunktion variable, valueals Argumente würde für mich nicht funktionieren. Auch wenn Sie Ausdruck verwenden möchten, müssen Sie lapply verwenden und können nicht einfach verwendenarr[val] , da das Argument für die Funktion ein data.frame ist.

Dieser Code hat funktioniert:

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)
reox
quelle
3

Da ich Beiträge noch nicht kommentieren darf, veröffentliche ich dies separat als Nachtrag zu Vince's Antwort und son520804's Antwort . Kredit geht an sie.

Son520804:

Verwenden von Iris-Daten:

Ich
gehe davon aus: Sie haben das Paket dplyr installiert, das über den praktischen Befehl mutate verfügt, und Ihr Datensatz heißt Survey. survey %>% mutate(Hosp1 = Hospital1, Hosp2 = Hospital2,........) Mit diesem Befehl können Sie Spalten umbenennen, alle anderen Spalten bleiben jedoch erhalten. Dann machen Sie das gleiche facet_wrap, es geht Ihnen jetzt gut.

Anhand des Iris-Beispiels von Vince und des Teilcodes von son520804 habe ich dies mit der Mutate-Funktion gemacht und eine einfache Lösung erzielt, ohne den Originaldatensatz zu berühren. Der Trick besteht darin, einen Ersatznamenvektor zu erstellen und mutate () in der Pipe zu verwenden, um die Facettennamen vorübergehend zu korrigieren:

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

In diesem Beispiel sehen Sie, dass die Ebenen von i $ Species vorübergehend in entsprechende allgemeine Namen geändert werden, die im Vektor new_names enthalten sind. Die Zeile enthält

mutate(Species=new_names) %>%

kann leicht entfernt werden, um die ursprüngliche Benennung anzuzeigen.

Achtung: Dies kann leicht zu Fehlern in Namen führen, wenn der Vektor new_name nicht korrekt eingerichtet ist. Es wäre wahrscheinlich viel sauberer, eine separate Funktion zu verwenden, um die variablen Zeichenfolgen zu ersetzen. Beachten Sie, dass der Vektor new_name möglicherweise auf unterschiedliche Weise wiederholt werden muss, um der Reihenfolge Ihres ursprünglichen Datensatzes zu entsprechen. Bitte überprüfen Sie doppelt und dreifach, ob dies korrekt erreicht wurde.

Alexander Kielland
quelle
Es kann ein bisschen schöner sein zu verwenden: new_names <- c('setosa' = 'Bristle-pointed iris', 'versicolor' = 'Poison flag iris', 'virginica' = 'Virginia iris')und dann in der Mutate könnten Sie eine neue Spalte so erstellen:mutate(Spec = new_names[Species])
filups21
3

Das funktioniert bei mir.

Definieren Sie einen Faktor:

hospitals.factor<- factor( c("H0","H1","H2") )

und verwenden, in ggplot():

facet_grid( hospitals.factor[hospital] ~ . )
Hernán Castelo
quelle
2

Nur die Antwort von naught101 erweitern - das Verdienst geht an ihn

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

Sie müssen lediglich eine Liste mit Name-zu-Name-Zuordnung erstellen

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

und plot_labeller()mit neuen Standardargumenten neu definieren :

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

Und dann:

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

Alternativ können Sie für jede gewünschte Etikettenänderung eine eigene Funktion erstellen.

user4786271
quelle
2

Ich habe eine andere Möglichkeit, dasselbe Ziel zu erreichen, ohne die zugrunde liegenden Daten zu ändern:

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

Was ich oben getan habe, ist das Ändern der Beschriftungen des Faktors im ursprünglichen Datenrahmen, und das ist der einzige Unterschied zu Ihrem ursprünglichen Code.

du auch
quelle
1

Haben Sie versucht, die spezifischen Ebenen Ihres HospitalVektors zu ändern ?

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"
philiporlando
quelle
1

Ich habe das Gefühl, ich sollte meine Antwort darauf hinzufügen, weil ich ziemlich lange gebraucht habe, um diese Arbeit zu machen:

Diese Antwort ist für Sie, wenn:

  • Sie möchten Ihre Originaldaten nicht bearbeiten
  • wenn Sie Ausdrücke benötigen (bquote ) in Ihren Labels und
  • wenn Sie die Flexibilität eines separaten Beschriftungsnamenvektors wünschen

Ich habe die Beschriftungen im Grunde genommen in einen benannten Vektor eingefügt, damit die Beschriftungen nicht verwirrt oder vertauscht werden. Der labellerAusdruck könnte wahrscheinlich einfacher sein, aber das funktioniert zumindest (Verbesserungen sind sehr willkommen). Beachten Sie das `(hintere Anführungszeichen), um den Facettenfaktor zu schützen.

n <- 10
x <- seq(0, 300, length.out = n)

# I have my data in a "long" format
my_data <- data.frame(
  Type = as.factor(c(rep('dl/l', n), rep('alpha', n))),
  T = c(x, x),
  Value = c(x*0.1, sqrt(x))
)

# the label names as a named vector
type_names <- c(
  `nonsense` = "this is just here because it looks good",
  `dl/l` = Linear~Expansion~~Delta*L/L[Ref]~"="~"[%]", # bquote expression
  `alpha` = Linear~Expansion~Coefficient~~alpha~"="~"[1/K]"
  )


ggplot() + 
  geom_point(data = my_data, mapping = aes(T, Value)) + 
  facet_wrap(. ~ Type, scales="free_y", 
             labeller = label_bquote(.(as.expression(
               eval(parse(text = paste0('type_names', '$`', Type, '`')))
               )))) +
  labs(x="Temperature [K]", y="", colour = "") +
  theme(legend.position = 'none')

Geben Sie hier die Bildbeschreibung ein

dani
quelle
1

Einfache Lösung (von hier ):

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)
Nick
quelle
0

Nachdem er eine Weile zu kämpfen, was ich gefunden habe , ist , dass wir verwenden können fct_relevel()und fct_recode()von forcatsin Verbindung , die Reihenfolge der Facetten zu verändern als auch die Facette Etiketten fixieren. Ich bin nicht sicher, ob es vom Design unterstützt wird, aber es funktioniert! Schauen Sie sich die folgenden Diagramme an:

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

Erstellt am 2020-02-16 durch das reprex-Paket (v0.3.0)

Ashirwad
quelle