2012-07-06 16 views
5

Rozważmy następujący ramkę danych:Spójne kolory legenda z qplot

x = read.table(text = 'Lo Re Pe 
1 T 33 
1 F 22 
1 H 11 
2 T 22 
2 F 22', header = TRUE) 

oraz następujące działki:

qplot(factor(Lo), data=x, geom='bar', fill=Re, weight=Pe, 
     xlab='L', main='Title', ylab='Pe') 

Teraz rozważmy tę ramkę danych:

x <- read.table(text = 'Lo Re Pe 
1 D 33 
1 K 22 
2 D 22 
2 K 22', header=TRUE) 

z tym samym qplot komunikat.

Kolory przypisane do każdej wartości Re nie są zgodne między poletkami, dlatego trudno jest bezpośrednio porównać wykresy.

Jak mogę określić, że Re wartość T powinna być zawsze „Red”, na przykład, że Re wartość F zawsze powinien być „Blue”, na przykład, tak że komenda qplot zawsze używa spójnych kolory dla każdego Re wartość, niezależnie od zawartości ramki danych? Istnieje skończona i znana liczba wartości dla Re, więc mogłem określić je wszystkie.

Próbowałem następujących gdy ramka danych zawartych wartościami T, F i H:

qplot(factor(Lo), data=x, geom='bar', fill=Re, weight=Pe, 
     xlab='Loci', main='Title', ylab='Pe', 
     scale_fill_manual(values=c("Blue","Red","Green"),labels=c("T","F","H"))) 

ale R zgłasza błąd o nieprawidłowej długości i nie produkują działkę.

Rozwiązanie to pozwoli mi określić kolory dla wszystkich możliwych wartości Re, nawet jeśli wszystkie te mogą nie być obecne w ramce danych.

+0

Może chcesz przekazać nam powtarzalny przykład? http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example –

+0

@ RomanLuštrik: Gotowe. Przerobiono całkowicie pytanie. – SabreWolfy

+2

Myślę, że to będzie działać poprawnie, jeśli tylko użyjesz współczynników o tych samych poziomach i 'scale_colour_discrete (drop = FALSE)' –

Odpowiedz

6

Jest to całkowicie możliwe przy użyciu modułowej natury ggplot. Zamierzam zalecić, abyś jednak rzucił qplot i przełączył się na używanie ggplot(). Nic cię to nie będzie kosztować i na dłuższą metę będzie wygodniejsze, ponieważ bardziej nadaje się do robienia "skomplikowanych" rzeczy.

Zacznijmy swoimi dwoma zestawami danych:

x1 = read.table(text = 'Lo Re Pe 
1 T 33 
1 F 22 
1 H 11 
2 T 22 
2 F 22', header = TRUE) 

x2 <- read.table(text = 'Lo Re Pe 
1 D 33 
1 K 22 
2 D 22 
2 K 22', header=TRUE) 

Teraz tutaj jest to Twoja pierwsza fabuła, ale w języku ggplot():

p <- ggplot(x1,aes(x = factor(Lo))) + 
     geom_bar(aes(fill = Re,weight = Pe)) + 
     labs(x = 'L',y = 'Pe') + 
     opts(title = 'Title') 

Aby zachować kolor spójne działek oraz zapobieganie nieużywane kolory od pojawienia się w legendzie, po prostu utworzymy główny klucz koloru i przekażemy tylko potrzebny podzbiór w naszej skali:

color_key <- c('red','blue','green','black','orange') 
#If Re is a character variable: 
names(color_key) <- unique(c(x1$Re,x2$Re)) 
#If Re is a factor: 
names(color_key) <- unique(c(as.character(x1$Re),as.character(x2$Re))) 

(Można też zrobić coś podobnego przy użyciu funkcji levels, ale chciałem aby zabezpieczyć się przed tym poziomów, które nie pojawiają się w zbiorze danych.)

Oczywiście, można wybrać niezależnie kolory lubisz.Teraz mogę dostosować skalować fill na naszej działce p przepuszczając tylko ten segment color_key które są istotne dla scale_fill_manual:

p + scale_fill_manual(values = color_key[names(color_key) %in% x1$Re]) 

enter image description here

Dodatkowo, jeśli Działki wszystko naprawdę mają taką samą strukturę, my nawet nie trzeba replikować połączenia ggplot w kółko. Możemy po prostu stosować naszą działkę p do nowego zestawu danych:

p1 <- p %+% x2 

a następnie dodać skalować fill w ten sam sposób:

p1 + scale_fill_manual(values = color_key[names(color_key) %in% x2$Re]) 

enter image description here

Wreszcie niech mieszać i łączyć się nowy zestaw danych:

x3 <- rbind(x1[1:2,],x2[3:4,]) 

sam proces znowu działa:

p3 <- p %+% x3 
p3 + scale_fill_manual(values = color_key[names(color_key) %in% x3$Re]) 

enter image description here

+0

Dzięki za szczegółową odpowiedź. Pracuję nad tym teraz. Linia zaczynająca się od 'p + scale_fill_manual' daje błąd' Błąd: Niewystarczające wartości w ręcznej skali. 3 potrzebne, ale podano tylko 0. "I nie działki. – SabreWolfy

+0

@SabreWolfy Być może nie uruchomiłeś kodu w moim post _exactly_, ponieważ wygląda, ponieważ wszystko działa dobrze dla mnie. Uruchom każdy element w sekwencji (w tym generowanie 'x1' i' x2') i sprawdź, czy każdy z nich działał poprawnie. – joran

+0

Tak, zrobiłem to :) Skopiowałem i wkleiłem każdą sekcję w kolejności. Polecenie 'unique' zwraca tylko 3 wartości. Próbuję dowiedzieć się dlaczego teraz. – SabreWolfy