Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
671 views
in Technique[技术] by (71.8m points)

r - How do I combine aes() and aes_string() options

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"))

enter image description here

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()?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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"))

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...