2015-02-28 15 views
9

Powiedzmy mam działkę jak tenJak połączyć AES() i aes_string() Opcje

library(ggplot2) 
ggplot(mtcars, aes(x=wt)) + ylab("") + 
    geom_line(aes(y=mpg, color="one")) + 
    geom_line(aes(y=qsec, color="two")) + 
    scale_color_manual(name="Val", values=c(one="#105B63",two="#BD4932")) 

enter image description here

gdzie jestem wykreślania dwie linie i określającego grupę kolorów dla każdego. Teraz załóżmy, że chcę, aby określić nazwy zmiennych dynamicznie jako wartości znakowych co oznacza, że ​​trzeba użyć aes_string(). Gdy próbuję

v1<-"mpg" 
v2<-"qsec" 
ggplot(mtcars, aes(x=wt)) + ylab("") + 
    geom_line(aes_string(y=v1, color="one")) + 
    geom_line(aes_string(y=v2, color="two")) + 
    scale_color_manual(name="Val", values=c(one="#105B63",two="#BD4932")) 

pojawia się błąd

Error in eval(expr, envir, enclos) : object 'one' not found 

bo teraz aes_string() próbuje analizować wartość koloru, gdy chcę tylko dosłownej wartości znaku. I jeśli próbuję

ggplot(mtcars, aes(x=wt)) + ylab("") + 
    geom_line(aes_string(y=v1), aes(color="one")) + 
    geom_line(aes_string(y=v2), aes(color="two")) + 
    scale_color_manual(name="Val", values=c(one="#105B63",two="#BD4932")) 

uzyskać

Error: ggplot2 doesn't know how to deal with data of class uneval 

przypuszczalnie dlatego, że warstwa nie umie obsłużyć dwie dyrektywy estetyczne.

Jak mogę łączyć estetykę aes() i aes_string() lub jak określić wartości literalne dla aes_string()?

Odpowiedz

18

Jeśli chcesz określić literalną wartość znaku w aes_string(), najłatwiej byłoby użyć wartości shQuote(). Na przykład

ggplot(mtcars, aes(x=wt)) + ylab("") + 
    geom_line(aes_string(y=v1, color=shQuote("one"))) + 
    geom_line(aes_string(y=v2, color=shQuote("two"))) + 
    scale_color_manual(name="Val", values=c(one="#105B63",two="#BD4932")) 

To działa, ponieważ aes_string() faktycznie działa parse(text=) na każdym z wartościami parametrów. Funkcja shQuote() dodaje cytaty wokół wartości twojego znaku, aby podczas analizowania wartości uzyskać wartość znaku zamiast symbolu/nazwy. Porównaj te dwa wywołania:

class(parse(text="a")[[1]]) 
# [1] "name" 
class(parse(text=shQuote("a"))[[1]]) 
# [1] "character" 

Alternatywnie możesz pomyśleć o połączeniu dyrektyw aes(). Funkcje aes() po prostu zwracają listę z klasą uneval. Możemy zdefiniować funkcję łączenia/łączenia tych list. Na przykład możemy zdefiniować dodawanie

`+.uneval` <- function(a,b) { 
    `class<-`(modifyList(a,b), "uneval") 
} 

Teraz możemy zrobić

ggplot(mtcars, aes(x=wt)) + ylab("") + 
    geom_line(aes_string(y=v1) + aes(color="one")) + 
    geom_line(aes_string(y=v2) + aes(color="two")) + 
    scale_color_manual(name="Val", values=c(one="#105B63",two="#BD4932")) 
+3

Dobrze, rozwiązałeś problem, którego nawet nie zauważyłem;) (+1.5) – BrodieG

8

Jako alternatywę dla użytkownika @ MrFlick doskonałą odpowiedź, można również użyć aes_q i obrócić zawartość zmiennych wpływających name s:

ggplot(mtcars, aes(x=wt)) + ylab("") + 
    geom_line(aes_q(y=as.name(v1), color="one")) + 
    geom_line(aes_q(y=as.name(v2), color="two")) + 
    scale_color_manual(name="Val", values=c(one="#105B63",two="#BD4932"))