web-dev-qa-db-de.com

ggplot: Wie man Facettenbeschriftungen ändert?

Ich habe den folgenden ggplot-Befehl 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 ~ .) 
  + opts(panel.background = theme_blank()) 

produzieren

alt text

Ich möchte jedoch die Beschriftungen facet in etwas kürzeres ändern (z. B. Hosp 1, Hosp 2 ...), da sie jetzt zu lang sind und verkrampft wirken (eine Erhöhung der Höhe des Diagramms ist keine Option wäre zu viel Platz im Dokument). Ich habe mir die Seite facet_grid help angesehen, kann aber nicht herausfinden, wie.

182

Ändern Sie die Namen der zugrunde liegenden Faktoren:

# 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 ~ .)
104
Vince

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

Angenommen, Ihr Diagramm wird durch den group-Teil Ihres Datenrahmens gebildet, der die Ebenen control, test1, test2 hat. Erstellen Sie dann eine Liste, die nach diesen Werten benannt wird:

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 'Label'-Funktion und fügen Sie sie in Ihren facet_grid-Aufruf ein:

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

Hierbei werden die Ebenen des Datenrahmens zur Indexierung der Liste hospital_names verwendet, wobei die Listenwerte (die korrekten Namen) zurückgegeben werden.


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 so etwas tun:

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

Dabei sind facet1_names und facet2_names vordefinierte Namenslisten, die durch die Facettenindexnamen indiziert werden ('Hostpital # 1' usw.).


Edit: Die obige Methode schlägt fehl, wenn Sie eine Variablen-/Wertkombination übergeben, die der Etikettierer nicht kennt. Sie können einen Fail-Safe 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 von wie man Strip.text-Labels in ggplot mit Facette und Marge ändert = TRUE


edit: WARNING: Wenn Sie diese Methode verwenden, um durch eine Zeichen-Spalte zu facetten, erhalten Sie möglicherweise falsche Beschriftungen. Siehe diesen Fehlerbericht . in den letzten Versionen von ggplot2 behoben.

249
naught101

Hier ist eine weitere Lösung, die der von @ naught101 gegebenen Lösung entspricht, jedoch einfacher ist und keine Warnung auf die neueste Version von ggplot2 auslöst.

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 von @ naught101 angegebenen Codes in ändern

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

Hoffe das hilft.

170
mbiron

So habe ich es mit facet_grid(yfacet~xfacet) mit 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 Aufruf an as_labeller() enthält - etwas, mit dem ich mich längere Zeit herumgeschlagen habe.

Dieser Ansatz basiert auf dem letzten Beispiel auf der Hilfeseite Coerce-to-Labeler-Funktion

20
bovender

Wenn Sie zwei Facetten hospital und room haben, aber nur eine umbenennen möchten, können Sie Folgendes verwenden:

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

Zum Umbenennen von zwei Facetten mit dem vektorbasierten Ansatz (wie in der Antwort von naught101) können Sie Folgendes tun:

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

Diese Lösung ist sehr nahe an dem, was @domi hat, aber der Name wird verkürzt, 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))

 enter image description here

7
Roman Luštrik

Beachten Sie, dass diese Lösung nicht gut funktioniert, falls ggplot weniger Faktoren aufweist, als Ihre Variable tatsächlich enthält (was passieren könnte, wenn Sie beispielsweise ein Subsetting durchgeführt haben):

 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 ursprünglichen Datensatz oder in der Labbeler-Funktion zu löschen:

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

Sowohl facet_wrap als auch facet_grid akzeptieren auch die Eingabe von ifelse als Argument. Wenn also die für die Facettierung 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 enthält, muss die ifelse-Anweisung geschachtelt sein.

Als Nebeneffekt ermöglicht dies auch das Anlegen der Gruppen innerhalb des Aufrufs ggplot.

4
lillemets

Hinzufügen einer anderen Lösung ähnlich der von @ domi mit dem Analysieren von mathematischen Symbolen, hochgestellt, tiefgestellt, 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 von reprex package (v0.2.1.9000)

3
Tung

Da ich noch keine Beiträge kommentieren darf, poste ich dies separat als Anhang zu Vinces Antwort und son520804's Antwort . Kredit geht an sie.

Son520804:

mit Iris Daten:

Ich nehme an:
Sie haben das Paket dplyr installiert, das den praktischen Befehl mutate enthält, 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 mach das gleiche facet_wrap, es geht dir jetzt gut.

Mit dem Iris-Beispiel von Vince und dem Teilcode von son520804 habe ich dies mit der Mutate-Funktion gemacht und eine einfache Lösung erreicht, ohne den ursprünglichen Datensatz zu berühren. Der Trick besteht darin, einen Ersatznamensvektor zu erstellen und mutate () innerhalb 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 können Sie sehen, dass die Ebenen von i $ Species vorübergehend in entsprechende gebräuchliche Namen geändert werden, die im Vektor new_names enthalten sind. Die Zeile mit

mutate(Species=new_names) %>%

kann leicht entfernt werden, um die ursprüngliche Benennung zu enthüllen.

Vorsichtsmaßnahme: 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 Datasets zu entsprechen. Bitte überprüfen Sie zweimal und dreimal, ob dies korrekt durchgeführt wurde.

3

Die Definition der Etikettierfunktion mit variable, value als Argumente würde für mich nicht funktionieren. Wenn Sie expression verwenden möchten, müssen Sie lapply verwenden und können nicht einfach arr[val] verwenden, da das Argument der 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)
2
reox

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

Ich nehme an:

  • sie haben das Paket dplyr mit dem praktischen Befehl mutate installiert 
  • ihr Datensatz heißt survey.

    umfrage%>% mutieren (Hosp1 = Hospital1, Hosp2 = Hospital2, ........)

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

Dann machen Sie dasselbe facet_wrap, es geht Ihnen jetzt gut. 

2
son520804

Die EINFACHSTE Möglichkeit, OHNE die zugrunde liegenden Daten zu ändern, ist:

1) Erstellen Sie ein Objekt mit der as_labeller-Funktion 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)
1
Leinfloyd

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 gemacht habe, ist das Ändern der Beschriftungen des Faktors im ursprünglichen Datenrahmen, und das ist der einzige Unterschied im Vergleich zu Ihrem ursprünglichen Code.

1
ytu

Die Antwort von naught101 wird nur erweitert - Kredit 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))
    }
}

Was Sie tun müssen, ist eine Liste mit Name-zu-Name-Zuordnung zu erstellen

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

und definieren Sie plot_labeller() mit neuen Standardargumenten neu:

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 der gewünschten Etikettenänderungen eine eigene Funktion erstellen.

1
user4786271

Das funktioniert für mich.

Definieren Sie einen Faktor:

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

und verwenden Sie in ggplot():

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

Haben Sie versucht, die spezifischen Stufen Ihres Hospital-Vektors 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"
0
spacedSparking