Home > other >  Why isn't my custom errorbar function working in R?
Why isn't my custom errorbar function working in R?

Time:10-24

I have tried to make a function to quickly make an error bar based on a grouping factor and a numerical value as defined below:

#### Function ####
quick.error <- function(data,x,y){
  d <- data
  plot.d <- d %>%
    mutate(x = as.factor(x)) %>% 
    group_by(x) %>%
    summarise(
      sd = sd(y, na.rm = TRUE),
      mean = mean(y, na.rm=TRUE)
    ) %>% 
    ggplot(aes(x, 
               mean,
               fill=x))  
    geom_col(color = "black")  
    geom_errorbar(aes(ymin = mean-sd,
                      ymax = mean sd),
                  width = 0.2)  
    theme(legend.position = "none")
  return(plot.d)
}

However, when I try to run this with the iris dataset:

#### Test ####
quick.error(data=iris,
            x=Species,
            y=Petal.Length)

This gives me an error:

Error in `mutate()`:
! Problem while computing `x = as.factor(x)`.
Caused by error in `is.factor()`:
! object 'Species' not found

Running it explicitly with $ operators gives me a different issue:

#### Test ####
quick.error(data=iris,
            x=iris$Species,
            y=iris$Petal.Length)

As you can see here, it has made all the bars the same, I assume because it did not group the mean like it was supposed to:

enter image description here

How do I fix this problem?

CodePudding user response:

As I indicate in my comment, this is a typical non-standard evaluation problem. Here's a revised function that I believe gives you what you want.

quick.error <- function(data,x,y){
  d <- data
  plot.d <- d %>%
    mutate({{ x }} := as.factor({{ x }})) %>% 
    group_by({{ x }}) %>%
    summarise(
      sd = sd({{ y }}, na.rm = TRUE),
      mean = mean({{ y }}, na.rm=TRUE)
    ) %>% 
    ggplot(aes({{ x }}, 
               mean,
               fill={{ x }}))  
    geom_col(color = "black")  
    geom_errorbar(aes(ymin = mean-sd,
                      ymax = mean sd),
                  width = 0.2)  
    theme(legend.position = "none")
  return(plot.d)
}

quick.error(data=iris,
            x=Species,
            y=Petal.Length)

enter image description here

CodePudding user response:

Passing unquoted column names to a function

... requires injection with the embracing operator {{ or, in more complex cases, the injection operator !!.

For more on that see e.g. this vignette.

Hence you could make your function work by wrapping x and y inside your function in {{:

quick.error <- function(data, x, y) {
  d <- data
  plot.d <- d %>%
    mutate(x = as.factor({{ x }})) %>%
    group_by(x) %>%
    summarise(
      sd = sd({{ y }}, na.rm = TRUE),
      mean = mean({{ y }}, na.rm = TRUE)
    ) %>%
    ggplot(aes(x,
      mean,
      fill = x
    ))  
    geom_col(color = "black")  
    geom_errorbar(aes(
      ymin = mean - sd,
      ymax = mean   sd
    ),
    width = 0.2
    )  
    theme(legend.position = "none")

  return(plot.d)
}

library(ggplot2)
library(dplyr)

quick.error(
  data = iris,
  x = Species,
  y = Petal.Length
)

  • Related