如何在ggplot2中混合aes_()和算术计算?

How to mix aes_() and arithmetic calculation in ggplot2?

我正在尝试调整 Rggplot2 包中的以下脚本中的 xymax 以调整 errorbar 的绘图坐标,但是它 returns 错误。

  gplot <- function(prd) {

        ggplot() +
        geom_polygon(data=shp.t,aes(x=long,y=lat,group=group),
                      fill="white",colour="grey") +
        ## Plot errorbar
        geom_errorbar(data=te10.cent,size=2,colour="red",
                      alpha=.8,width=0,
                      aes_(x=quote(long.cent)-350,ymin=quote(lat.cent),       
                                 ymax=quote(lat.cent)+prd))
        }
gplot("Field Name") # Not number but field name of the data frame

(抱歉,我无法上传我正在使用的实际数据框。)

这些是我面临的错误:

Error in quote(lat.cent) + prd * .pt : non-numeric argument to binary Operator
Error in quote(lat.cent)+prd * .pt : non-numeric argument to binary Operator

如果从脚本中省略 -350+prd 或者在数据框中使用 'aes' 和实际变量,它在这两种情况下都有效。 我尝试了其他脚本; "long.cent"-350"lat.cent"+prd 而不是上面的脚本,但是它也 returns 同样的错误。

我搜索了解决方案,但所有解决方案都解释了如何在不混合参数和算术计算的情况下使用 aes_。我需要将非标准表达式与算术计算混合来调整我的情节,但是如何?

我相信这会解决您的问题:

gplot <- function(prd) {

  ggplot() +
    geom_polygon(data = shp.t,
                 aes_(x = ~long,
                      y = ~lat,
                      group = ~group),
                 fill = "white",
                 colour = "grey") +
    ## Plot errorbar
    geom_errorbar(data = te10.cent,
                  size = 2,
                  colour = "red",
                  alpha = .8,
                  width = 0,
                  aes_(x = ~long.cent - 350,
                       ymin = ~lat.cent,       
                       ymax = ~lat.cent + prd))
}

可重现的例子:

部分数据:

library(tidyverse)

data(iris)

iris %>%
  group_by(Species) %>%
  summarise_all(~mean(.)) -> summed_iris

gplot <- function(prd){
  ggplot(summed_iris) +
    geom_col(aes_(x = ~Species,
                  y = ~Sepal.Length))+
    geom_errorbar(aes_(x = ~Species,
                       ymin = ~Sepal.Length -prd,
                       ymax = ~Sepal.Length + prd))

}

gplot(0.5)

编辑:评论中的问题:

prd 是数据的列名的情况下,最好预先计算值:

gplot <- function(prd){
  ymin <-  with(summed_iris, get("Sepal.Length") - get(prd))
  ymax <-  with(summed_iris, get("Sepal.Length") + get(prd))
  summed_iris <- data.frame(summed_iris, ymin, ymax)
  ggplot(summed_iris) +
    geom_col(aes_(x = ~Species,
                  y = ~Sepal.Length))+
    geom_errorbar(aes_(x = ~Species,
                       ymin = ~ymin,
                       ymax = ~ymax))

}
gplot("Petal.Length")

随着即将推出的 ggplot2 2.3.0(将于 2018 年 6 月下旬发布),aes_(...) 被软弃用,建议使用 tidy eval。这意味着在此处的上下文中,当您想要变量 prd 的内容而不是符号 prd.

时,您可以编写 !!prd
library(ggplot2)
library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union

iris %>%
  group_by(Species) %>%
  summarise_all(~mean(.)) -> summed_iris

gplot <- function(prd){
  ggplot(summed_iris) +
    geom_col(aes(x = Species, y = Sepal.Length)) +
    geom_errorbar(
      aes(x = Species, ymin = Sepal.Length - !!prd, ymax = Sepal.Length + !!prd)
    )
}

gplot(0.5)

并且如果您希望函数gplot()能够像aes()一样使用符号,那么您需要在函数定义的开头添加一个enquo()。它捕获提供给函数的表达式以及封闭环境。

gplot <- function(prd){
  prd <- enquo(prd)
  ggplot(summed_iris) +
    geom_col(aes(x = Species, y = Sepal.Length)) +
    geom_errorbar(
      aes(x = Species, ymin = Sepal.Length - !!prd, ymax = Sepal.Length + !!prd)
    )
}

gplot(Petal.Length)

scale <- 1/5
gplot(scale*Petal.Length)