2010-08-13 21 views
151

Użyłem następujący ggplot polecenie:ggplot: Jak zmienić etykiety facetów?

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

produkować

alt text

Chciałbym zmienić aspekt etykiety, jednak coś krótszego (jak Hosp 1, Hosp 2 ...), ponieważ są teraz zbyt długie i wyglądają na ciasne (zwiększenie wysokości wykresu nie jest opcją, zajmie zbyt dużo miejsca w dokumencie). Spojrzałem na stronę pomocy facet_grid, ale nie mogę się dowiedzieć, jak to zrobić.

Odpowiedz

81

zmieniają podstawowej nazwy poziom czynnika z czymś takim:

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

Świetnie, działa dobrze; chociaż wolałbym rozwiązanie, które nie zmienia podstawowych danych, rozwiązał mój problem, więc mogłem poruszać się z moją pracą. Dziękuję Ci. – wishihadabettername

+9

@wishihadabettername: Aby uniknąć zmiany danych podstawowych, możesz użyć: 'ggplot (transformacja (tęczówka, gatunek = c (" S "," Ve "," Vi ") [jako numeryczne (gatunek)]), aes (Petal.Length)) + stat_bin() + facet_grid (Gatunek ~.) ' –

+0

powiązane ... jeśli chcesz, aby etykieta panelu była wyrażeniem bquote() (np.' Poziomy (x $ wymiary) <- c (bquote (Area ~~ (cm^2)), bquote (Length ~~ (cm))) ') nie pojawi się w wyrażeniu matematycznym. Jak pokazać wyrażenia jako etykiety aspektu? –

210

o to rozwiązanie, które pozwala uniknąć edycji danych:

Wypowiedz Działka szlifowanych przez group część swojego dataframe, który ma poziomy control, test1, test2, a następnie utworzyć listę nazwany przez tych wartości:

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

następnie utworzyć funkcję „etykietowania” i przesunąć do swojej facet_grid rozmowy:

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

ta wykorzystuje poziomy ramki danych do indeksowania lista hospital_names, wracając wartości liście (poprawnych nazw).


Należy pamiętać, że działa to tylko wtedy, gdy masz tylko jedną zmienną faceting. Jeśli masz dwa aspekty, to funkcja etykietowania musi zwracać inny wektor nazw dla każdego aspektu. Można to zrobić z czymś takim:

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

Gdzie facet1_names i facet2_names są predefiniowane listy nazwisk indeksowanych przez nazwy indeksu aspekt („Hostpital # 1”, etc.).


Edit: Powyższa metoda nie powiedzie się, jeśli przechodzą kombinacji zmienna/wartość, że etykietująca nie wie. Możesz dodać bezawaryjnego nieznanych zmiennych tak:

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

Odbierz adaptacją how to change strip.text labels in ggplot with facet and margin=TRUE


edit: UWAGA: jeśli używasz tej metody do aspektu przez kolumnę znak, możesz otrzymywać niepoprawne etykiety. Zobacz this bug report. poprawiono w najnowszych wersjach ggplot2.

+0

To działa jeden tbh –

+8

Przyjemnie, ale nie będzie działać z facet_wrap, natomiast rozwiązanie @Vince będzie działało również z facet_wrap. –

+0

@ArnaudAmzallag: Dokładnie, ale jeśli ktoś ma ochotę poświęcić trochę czasu, [może to w przyszłości] (https://github.com/hadley/ggplot2/issues/25). – naught101

7

Zauważ, że to rozwiązanie nie będzie działać dobrze w przypadku ggplot pokaże mniej czynników niż zmienna faktycznie zawiera (co może się zdarzyć, jeśli były na przykład podzbiorów):

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) 

Prostym rozwiązaniem (oprócz dodawania Wszystkie niewykorzystane czynniki names_li, które mogą być uciążliwe) jest spadek nieużywane czynniki droplevels(), albo w oryginalnym zbiorze lub w funkcji labbeler patrz:

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

Wystarczy rozszerzenie odpowiedź naught101 za - kredyt idzie do niego

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

Co trzeba zrobić, to stworzyć listę z nazwa na nazwę mapowania

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

i przedefiniować plot_labeller() nowe domyślne argumenty

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

, a następnie:

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

Alternatywnie możesz utworzyć dedykowaną funkcję dla każdej zmiany etykiety, którą chcesz mieć.

116

Oto inne rozwiązanie, które jest zgodne z duchem podanym przez @ naught101, ale prostsze, a także nie wyświetla ostrzeżenia o najnowszej wersji ggplot2.

Zasadniczo najpierw utworzyć nazwanego wektor znaków

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

A następnie użyć go jako etykieciarki, tylko poprzez modyfikację ostatnią linię kodu podanego przez @ naught101 do

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

Mam nadzieję że to pomoże.

+0

Która wersja ggplot2 to 'as_labeller' in? Znalazłem kod źródłowy dla repozytorium [CRAN GitHub] (https://github.com/hadley/ggplot2/blob/master/R/facet-labels.r), ale po aktualizacji do najnowszej wersji (w CRAN !) Wydaje mi się, że nie mam tej funkcji. –

+0

To dziwne. Zaktualizowałem również poprzez CRAN. Oto dokumentacja http://docs.ggplot2.org/dev/as_labeller.html – mbiron

+2

To jest fajne. Co się dzieje, gdy masz dwie zmienne w swojej siatce aspektów?Jak "szpital ~ gender" czy coś takiego? Czy istnieje sposób używania etykieciarek na obu osiach? Nie widzę niczego oczywistego w dokumentach. – naught101

11

Jeśli masz dwa aspekty hospital i room ale chce zmienić nazwę tylko jeden, można użyć:

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

do zmiany nazw dwa aspekty stosując podejście wektor oparte (jak w odpowiedzi naught101 jest), można zrobić :

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

mam inny sposób, aby osiągnąć ten sam cel bez zmiany danych podstawowych:

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

To, co zrobiłem powyżej, zmienia etykiety czynnika w oryginalnej ramce danych, i to jest jedyna różnica w porównaniu z oryginalnym kodem.

9

Oto jak to zrobiłem z facet_grid(yfacet~xfacet) użyciu ggplot2, wersja 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") 
    ) 
) 

pamiętać, że ten nie zawiera wezwanie do as_labeller() - coś, co z trudem przez chwilę.

To podejście zostało zainspirowane ostatnim przykładem na stronie pomocy: Coerce to labeller function.

+0

to działa !!! Nie mogłem zastosować innych rozwiązań, ponieważ niektóre z sugerowanych rozwiązań były przestarzałe w obecnych wersjach ggplot2. – yanes

1

Zarówno facet_wrap, jak i facet_grid jako argument przyjmują również dane wejściowe z ifelse. Więc jeśli zmienna wykorzystywane do szlifowaniem jest logiczne, rozwiązanie jest bardzo proste:

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

Jeśli zmienna ma więcej kategorii, oświadczenie ifelse musi być nested.

Jako efekt uboczny umożliwia to również tworzenie grup, które mają być fasetowane w ramach połączenia ggplot.

0

Myślę, że wszystkie inne rozwiązania są naprawdę pomocne, ale jest jeszcze inny sposób.

Przypuszczam:

  • masz zainstalowany pakiet dplyr, który ma dogodną komendę mutate i
  • zbioru danych o nazwie survey.

    Badanie%>% mutować (Hosp1 = Hospital1, Hosp2 = Hospital2, ........)

Komenda ta pozwala na zmianę nazwy kolumn, ale wszystkie pozostałe kolumny są przechowywane.

Następnie wykonaj to samo facet_wrap, nic ci nie jest.

Powiązane problemy