代码之家  ›  专栏  ›  技术社区  ›  Simon.S.A.

由于延迟计算,无法在ggplot中重用变量名

  •  1
  • Simon.S.A.  · 技术社区  · 7 年前

    我正在制作一个包含许多相似元素的ggplot。为了帮助我设计了一个生成单个元素的函数,我计划重用它。例如

    reusable.element = function(gg, params){
        x = some.calculation(params)
        y = some.calculation(params)
        gg + geom_line(aes(x,y))
    }
    gg = ggplot()
    gg = reusable.element(gg, params1)
    gg = reusable.element(gg, params2)
    print(gg)
    

    然而,R抱怨说它找不到 x .

    尽我所能确定这似乎是由于懒惰的评估。R正在尝试评估 只有在打印绘图时。例如:

    x1 = c(1,1)
    y1 = c(1,2)
    p = ggplot() + geom_point(aes(x1,y1))
    x1 = c(1)
    y1 = c(3)
    p = p + geom_point(aes(x1,y1))
    p
    

    只生成一个点的绘图,因为 x1 = c(1) 重写 x1 = c(1,1) .

    我知道我可以通过分配不同的变量名来解决这个问题。例如:

    x1 = c(1,1)
    y1 = c(1,2)
    p = ggplot() + geom_point(aes(eval(x1),eval(y1)))
    x2 = c(1)
    y2 = c(3)
    p = p + geom_point(aes(x2,y2))
    p
    

    (产生3个点的计划图)。但这将大大降低生成单个plot元素的任何函数的效率。

    1 回复  |  直到 7 年前
        1
  •  2
  •   Simon.S.A.    7 年前

    只有在写下我的全部问题后才找到答案: Force evaluation

    简而言之,使用 aes_ 而不是 aes 强制在编写时对美感进行评估(防止在绘制图形时进行延迟评估,并允许在函数中构建图形元素)。

    以下是@camille的评论 爱依斯_ . 请注意,您可能必须更新到 tidyverse rlang 使之工作的程序包。

    x1 = c(1,1)
    y1 = c(1,2)
    p = ggplot() + geom_point(aes(!!enquo(x1),!!enquo(y1)))
    x1 = c(1)
    y1 = c(1)
    p
    

    我认为这是 enquo 是评估'n'引用和 !! 作为引证。所以 !!enquo 在调用变量时强制对其求值。