如何组合aes()和aes_string()选项

MrF*_*ick 15 r ggplot2

假设我有这样的情节

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"))
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

我正在绘制两条线并为每条线指定一个颜色组.现在让我们说我想动态地将变量名称指定为字符值,这意味着我需要使用aes_string().如果我尝试

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"))
Run Code Online (Sandbox Code Playgroud)

我收到了错误

Error in eval(expr, envir, enclos) : object 'one' not found
Run Code Online (Sandbox Code Playgroud)

因为现在aes_string()我只是想要一个文字字符值来解析颜色值.如果我试试

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"))
Run Code Online (Sandbox Code Playgroud)

我明白了

Error: ggplot2 doesn't know how to deal with data of class uneval
Run Code Online (Sandbox Code Playgroud)

大概是因为该层不知道如何处理两个美学指令.

如何组合aes()aes_string()美观或如何指定文字字符值aes_string()

MrF*_*ick 26

如果要指定字符文字值aes_string(),最简单的方法是shQuote()引用该值.例如

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"))
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为aes_string()实际上运行parse(text=)在每个参数值上.该shQuote()函数在字符值周围添加引号,以便在解析值时,返回一个字符值而不是符号/名称.比较这两个电话

class(parse(text="a")[[1]])
# [1] "name"
class(parse(text=shQuote("a"))[[1]])
# [1] "character"
Run Code Online (Sandbox Code Playgroud)

或者,您可能会考虑合并aes()指令.这些aes()函数实际上只返回一个类的列表uneval.我们可以定义一个函数来组合/合并这些列表.例如,我们可以定义添加

`+.uneval` <- function(a,b) {
    `class<-`(modifyList(a,b), "uneval")
}
Run Code Online (Sandbox Code Playgroud)

现在我们可以做到

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"))
Run Code Online (Sandbox Code Playgroud)

  • 很好,你解决了我甚至没有意识到的问题;)(+ 1.5) (4认同)

Rol*_*and 10

作为@ MrFlick的优秀答案的替代方案,您还可以使用aes_q变量的内容并将其变为names:

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"))
Run Code Online (Sandbox Code Playgroud)


Moo*_*per 7

有了ggplot2 V3.0.0它变得非常简单:

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