How do I combine aes() and aes_string() options
ggplot2, r
Solution
Update: ggplot >=v3.0 supports tidy evaluation and the `.data` pronoun. The recommended way to use both character values and literal values would be
ggplot(mtcars, aes(x=wt)) + ylab("") +
geom_line(aes(y=.data[[v1]], color=one)) +
geom_line(aes(y=.data[[v2]], color=two)) +
scale_color_manual(name="Val", values=c(one="#105B63",two="#BD4932"))
If you want to specify a character literal value in `aes_string()`, the easiest thing would be to use `shQuote()` to quote the value. For example
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"))
This works because `aes_string()` actually runs `parse(text=)` on each of the parameter values. The `shQuote()` function adds quotes around your character value so that when you parse the value, you get a character value back rather than a symbol/name. Compare these two calls
class(parse(text="a")[[1]])
# [1] "name"
class(parse(text=shQuote("a"))[[1]])
# [1] "character"
Alternatively, you might think of merging `aes()` directives. The `aes()` functions really just return a list with a class of `uneval`. We could define a function to combine/merge these list. For example we can define addition
`+.uneval` <- function(a,b) {
`class<-`(modifyList(a,b), "uneval")
}
Now we can do
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"))
Problem
Let's say I have a plot like this ``` 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")) ``` where I am plotting two lines and specifying a color group for each. Now let's say I want to specify the variables names dynamically as character values which means I'll need to use `aes_string().` If I try ``` 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")) ``` I get the error ``` Error in eval(expr, envir, enclos) : object 'one' not found ``` because now `aes_string()` is trying to parse the color value when I just want a literal character value. And if I try ``` 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")) ``` I get ``` Error: ggplot2 doesn't know how to deal with data of class uneval ``` presumably because the layer doesn't know how to handle two aesthetic directives. How can I combine `aes()` and `aes_string()` aesthetics or how can I specify literal character values for `aes_string()`?