ggplot: jak zmienić etykiety facet?
Użyłem następującego polecenia 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 ~ .)
+ opts(panel.background = theme_blank())
Do produkcji
Chciałbym jednak zmienić etykietyaspekt na 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ą, zajęłoby to zbyt dużo miejsca w dokumencie). Spojrzałem na stronę pomocy facet_grid, ale nie mogę dowiedzieć się, jak.
14 answers
Zmień podstawowe nazwy poziomów czynnika na coś w stylu:
# 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 ~ .)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-13 01:40:03
Oto rozwiązanie, które pozwala uniknąć edycji danych:
Powiedz, że wykres jest obliczony przez group
część ramki danych, która ma poziomy control, test1, test2
, a następnie utwórz listę nazwaną tymi wartościami:
hospital_names <- list(
'Hospital#1'="Some Hospital",
'Hospital#2'="Another Hospital",
'Hospital#3'="Hospital Number 3",
'Hospital#4'="The Other Hospital"
)
Następnie utwórz funkcję 'labeller' i wciśnij ją do wywołania 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)
...
Wykorzystuje poziomy ramki danych do indeksowania listy hospital_names, zwracając wartości listy (poprawne nazwy).
Pamiętaj, że działa to tylko wtedy, gdy masz tylko jeden zmienna fasetująca. Jeśli masz dwa aspekty, funkcja etykietowania musi zwrócić inny wektor nazwy dla każdego aspektu. Można to zrobić za pomocą czegoś takiego:
plot_labeller <- function(variable,value){
if (variable=='facet1') {
return(facet1_names[value])
} else {
return(facet2_names[value])
}
}
Gdzie facet1_names
i facet2_names
są wstępnie zdefiniowanymi listami nazw indeksowanych przez nazwy indeksów facet ('Hostpital#1', itd.).
Edit: powyższa metoda nie powiedzie się, jeśli przekażesz kombinację zmienna / wartość, której etykieciarz nie zna. Możesz dodać zabezpieczenie przed awarią dla nieznanych zmiennych, takich jak to:
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))
}
}
Odpowiedź zaadaptowana z Jak zmienić pasek.etykiety tekstowe w ggplot z facet i margin=TRUE
edit: Ostrzeżenie : Jeśli używasz tej metody do facetowania przezznak kolumna, możesz otrzymać nieprawidłowe etykiety. Zobacz ten raport o błędzie . poprawiono w najnowszych wersjach ggplot2.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-01 07:52:09
Oto kolejne rozwiązanie, które jest w duchu tego podanego przez @ naught101, ale prostsze i również nie rzuca ostrzeżenia na najnowszą wersję ggplot2.
Zasadniczo, najpierw tworzysz nazwany 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 potem używasz go jako Etykieciarki, po prostu modyfikując ostatnią linijkę kodu podanego przez @ naught101 na
... + facet_grid(hospital ~ ., labeller = as_labeller(hospital_names))
Mam nadzieję, że to pomoże.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-15 21:29:27
Jeśli masz dwa aspekty hospital
i room
, ale chcesz zmienić nazwę tylko jednego, możesz użyć:
facet_grid( hospital ~ room, labeller = labeller(hospital = as_labeller(hospital_names)))
Do zmiany nazwy dwóch aspektów za pomocą podejścia wektorowego (jak w odpowiedzi naught101), można zrobić:
facet_grid( hospital ~ room, labeller = labeller(hospital = as_labeller(hospital_names),
room = as_labeller(room_names)))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-12 20:44:12
Oto Jak to zrobiłem z facet_grid(yfacet~xfacet)
używając 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")
)
)
Zauważ, że to nie zawiera wezwania do as_labeller()
-- czegoś, z czym przez jakiś czas zmagałem się.
To podejście jest inspirowane ostatnim przykładem na stronie pomocy wymuszanie funkcji labeller .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-01 07:46:48
Zauważ, że to rozwiązanie nie będzie działać dobrze w przypadku, gdy ggplot pokaże mniej czynników niż Twoja zmienna faktycznie zawiera (co mogłoby się zdarzyć, gdybyś był na przykład podzbiór):
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 (poza dodaniem wszystkich nieużywanych czynników w nazwach_li, co może być uciążliwe) jest usunięcie nieużywanych czynników za pomocą funkcji droplevels (), albo w oryginalnym zbiorze danych, albo w funkcji labbeler, Zobacz:
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)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-11 09:42:24
Zarówno facet_wrap
, jak i facet_grid
akceptują również dane wejściowe z ifelse
jako argument. Jeśli więc zmienna użyta do fasetowania jest logiczna, rozwiązanie jest bardzo proste:
facet_wrap(~ifelse(variable, "Label if true", "Label if false"))
Jeśli zmienna ma więcej kategorii, Instrukcja ifelse
musi być zagnieżdżona.
Jako efekt uboczny, pozwala to również na tworzenie grup w wywołaniu ggplot
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-08 12:12:28
Myślę, że wszystkie inne rozwiązania są naprawdę pomocne, aby to zrobić, ale jest jeszcze inny sposób.
Zakładam:
- zainstalowano pakiet
dplyr
, który posiada wygodne poleceniemutate
oraz -
Twój zestaw danych nazywa się
survey
.Ankieta %>% mutate (Hosp1 = Hospital1, Hosp2 = Hospital2,........)
To polecenie pomaga zmienić nazwę kolumn, jednak wszystkie pozostałe kolumny są zachowywane.
Więc zrób to samo, nic Ci nie jest.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-19 23:58:33
Tylko przedłużam odpowiedź naught101 -- 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))
}
}
To, co musisz zrobić, to utworzyć listę z mapowaniem nazwy na nazwę
clusteringDistance_names <- list(
'100'="100",
'200'="200",
'300'="300",
'400'="400",
'600'="500"
)
I przedefiniować plot_labeller()
z nowymi argumentami domyślnymi:
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 wprowadzić.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-17 14:05:12
Mam inny sposób na osiągnięcie tego samego celu bez zmiany podstawowych danych:
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, to zmiana etykiet czynnika w oryginalnej ramce danych, i to jest jedyna różnica w porównaniu z oryginalnym kodem.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-10 03:49:22
Definicja funkcji labeller z variable, value
jako argumentami nie byłaby dla mnie odpowiednia. Również jeśli chcesz użyć wyrażenia, musisz użyć lapply i nie możesz po prostu użyć arr[val]
, ponieważ argumentem funkcji jest data.rama.
Ten kod zadziałał:
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)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-04 14:59:25
Próbowałeś zmienić określone poziomy swojego wektora Hospital
?
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"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-28 06:48:28
Ponieważ nie mogę jeszcze komentować postów, zamieszczam to osobno jako dodatek do odpowiedziVince ' a ison520804 . To zasługa nich.
Son520804:
Użycie danych Iris:
Zakładam:
Zainstalowałeś pakiet dplyr, który posiada wygodne polecenie mutate oraz twój zestaw danych nazywa się survey.survey %>% mutate(Hosp1 = Hospital1, Hosp2 = Hospital2,........)
To polecenie pomaga zmienić nazwę kolumn, ale wszystkie pozostałe kolumny są zachowywane. Więc zrób to samo. facet_wrap, jesteś teraz w porządku.
Używając przykładu Iris Vince ' a i częściowego kodu son520804, zrobiłem to za pomocą funkcji mutate i osiągnąłem łatwe rozwiązanie bez dotykania oryginalnego zbioru danych. Sztuczka polega na stworzeniu wektora nazw i użyciu mutate() wewnątrz rury, aby tymczasowo skorygować nazwy aspektów: {]}
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 ~ .)
W tym przykładzie można zobaczyć poziomy i$Species są tymczasowo zmieniane na odpowiadające im nazwy zwyczajowe zawarte w wektorze new_names. Linia zawierająca
mutate(Species=new_names) %>%
Można łatwo usunąć, aby ujawnić oryginalne nazewnictwo.
Uwaga: może to łatwo wprowadzić błędy w nazwach, jeśli wektor new_name nie jest prawidłowo ustawiony. Prawdopodobnie byłoby dużo czystsze użycie oddzielnej funkcji do zastąpienia zmiennych łańcuchów. Należy pamiętać, że wektor new_name może wymagać powtórzenia na różne sposoby, aby dopasować kolejność oryginalnego zbioru danych. Prosimy o podwójne i potrójne sprawdzenie, czy jest to poprawne / align = "left" /
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-21 12:18:26
To rozwiązanie jest bardzo zbliżone do tego, co ma @domi, ale ma na celu skrócenie nazwy poprzez pobranie pierwszych 4 liter i ostatniej cyfry.
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))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-23 10:38:41