2015-09-12 20 views
7

Wykonuję teraz analizę w ggplot2 dla projektu i przez przypadek natknąłem się na niektóre (dla mnie) dziwne zachowanie, którego nie potrafię wyjaśnić. Kiedy piszę aes(x = cyl, ...), działka wygląda inaczej, co robi, jeśli przekażę tę samą zmienną za pomocą aes(x = mtcars$cyl, ...). Kiedy usuwam facet_grid(am ~ .) oba wykresy są takie same. Poniższy kod jest wzorowana kodu w moim projekcie, który generuje ten sam problem:Problem podczas przekazywania zmiennej z notacją na znak dolara do aes() w połączeniu z facet_grid() lub facet_wrap()

library(dplyr) 
library(ggplot2) 

data = mtcars 

test.data = data %>% 
    select(-hp) 


ggplot(test.data, aes(x = test.data$cyl, y = mpg)) + 
    geom_point() + 
    facet_grid(am ~ .) + 
    labs(title="graph 1 - dollar sign notation") 

ggplot(test.data, aes(x = cyl, y = mpg)) + 
    geom_point()+ 
    facet_grid(am ~ .) + 
    labs(title="graph 2 - no dollar sign notation") 

Oto obraz Wykres 1: graph 1 - dollar sign notation

Oto obraz wykresu 2: graph 2 - no dollar sign notation

Znalazłem, że mogę obejść ten problem, używając aes_string zamiast aes i przekazując nazwy zmiennych jako łańcuchy, ale chciałbym zrozumieć, dlaczego ggplot zachowuje się w ten sposób. Problem występuje również w podobnych próbach z facet_wrap.

Dużo za pomoc z góry! Czuję się bardzo niewygodne, jeśli nie rozumieją, że właściwie ...

+9

krótka odpowiedź brzmi: * nie * użyć '$' 'w AES()' – baptiste

+0

^_^po szoku dostałam dzisiaj, kiedy mój wykres nagle wszystko wyglądało dziwnie, nie będę robić to ponownie. Nadal chciałbym zrozumieć, co się dzieje, ponieważ nigdy wcześniej nie spotkałem się z tym problemem/zachowaniem. – Christoph

+1

gdy ggplot buduje wykres, jeśli dzieli zbiór danych dla każdej warstwy na grupy, zdefiniowane przez estetykę i fasetowanie.Aby ta grupa była wiarygodna, potrzebujesz zmiennych pochodzących z pojedynczego elementu data.frame, w przeciwnym razie ggplot może skończyć się przy użyciu innej kolejności dla współczynnika facylitacji i reszty mapowania. – baptiste

Odpowiedz

23

tl; dr

Nigdy użycie [ lub $ wewnątrz aes().


Rozważmy ilustracyjny przykład gdzie zmienna szlifowania f jest celowo w nieoczywistych kolejności w odniesieniu do x

d <- data.frame(x=1:10, f=rev(letters[gl(2,5)])) 

Teraz kontrast, co dzieje się z tych dwóch działek,

p1 <- ggplot(d) + 
    facet_grid(.~f, labeller = label_both) + 
    geom_text(aes(x, y=0, label=x, colour=f)) + 
    ggtitle("good mapping") 

p2 <- ggplot(d) + 
    facet_grid(.~f, labeller = label_both) + 
    geom_text(aes(d$x, y=0, label=x, colour=f)) + 
    ggtitle("$ corruption") 

enter image description here

możemy uzyskać lepsze wyobrażenie o tym, co dzieje się, patrząc na data.frame wewnętrznie wytworzoną przez ggplot2 dla każdego panelu,

ggplot_build(p1)[["data"]][[1]][,c("x","PANEL")] 

    x PANEL 
1 6  1 
2 7  1 
3 8  1 
4 9  1 
5 10  1 
6 1  2 
7 2  2 
8 3  2 
9 4  2 
10 5  2 

ggplot_build(p2)[["data"]][[1]][,c("x", "PANEL")] 

    x PANEL 
1 1  1 
2 2  1 
3 3  1 
4 4  1 
5 5  1 
6 6  2 
7 7  2 
8 8  2 
9 9  2 
10 10  2 

Druga działka ma niewłaściwy mapowanie, bo gdy ggplot tworzy data.frame dla każdego panel, wybiera wartości x w "złej" kolejności.

Dzieje się tak, ponieważ użycie $ przerywa połączenie między różnymi zmiennymi, które mają zostać odwzorowane (ggplot musi przyjąć, że jest to niezależna zmienna, która dla wszystkich, którzy wie, może pochodzić z dowolnego, odłączonego źródła). Ponieważ data.frame w tym przykładzie nie jest uporządkowana zgodnie z czynnikiem f, dane data.frames podzbioru używane wewnętrznie dla każdego panelu przyjmują błędną kolejność.

+0

Bardzo dziękuję za pomoc! Twój przykład jest niesamowity! – Christoph