Search code examples
rggplot2nseaesthetics

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


I am trying to adjust x and ymax in the following script in ggplot2 package in R to adjust plotting coordinates of errorbar, however it returns errors.

  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

(Sorry, I cannot upload the actual data frame that I am using.)

These are the errors that I am facing:

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

It works in both cases if -350 and +prd are omitted from the script or using 'aes' with actual variable in the data frame. I tried other scripts; "long.cent"-350 and "lat.cent"+prd instead of the above script, however it also returns the same error.

I searched for solutions but all of them explains how to use aes_ without mixing argument and arithmetic calculation. I need to mix non-standard expression with arithmetic calculation to adjust my plot but how?


Solution

  • I trust this will resolve your issue:

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

    reproducible example:

    some data:

    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)
    

    enter image description here

    EDIT: to the question in the comment:

    In the case when prd is the column name of the data perhaps it is best to precompute the values:

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

    enter image description here