【问题标题】:How do I combine aes() and aes_string() options如何组合 aes() 和 aes_string() 选项
【发布时间】:2015-02-28 03:02:04
【问题描述】:

假设我有这样的情节

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

我在其中绘制两条线并为每条线指定一个颜色组。现在假设我想将变量名称动态指定为字符值,这意味着我需要使用 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"))

我得到了错误

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

因为现在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"))

我明白了

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

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

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

【问题讨论】:

    标签: r ggplot2


    【解决方案1】:

    如果你想在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"))
    

    这是因为aes_string() 实际上对每个参数值运行parse(text=)shQuote() 函数在您的字符值周围添加引号,这样当您解析值时,您会得到一个字符值而不是符号/名称。比较这两个调用

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

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

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

    现在我们可以做

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

    【讨论】:

    • 很好,你解决了一个我什至没有意识到的问题;) (+1.5)
    【解决方案2】:

    作为@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"))
    

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 2020-12-31
        • 2019-03-10
        • 2016-05-02
        • 1970-01-01
        • 1970-01-01
        • 2015-10-31
        • 2023-01-24
        • 1970-01-01
        • 2015-09-30
        相关资源
        最近更新 更多