代码之家  ›  专栏  ›  技术社区  ›  Shawn Hemelstrand

为什么我的自定义errorbar函数不能在R中工作?

  •  1
  • Shawn Hemelstrand  · 技术社区  · 1 年前

    我尝试了一个函数,根据分组因子和如下定义的数值快速生成误差条:

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

    然而,当我尝试使用 iris 数据集:

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

    这给了我一个错误:

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

    使用显式运行它 $ 操作员给了我一个不同的问题:

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

    正如你在这里看到的,它使所有的条都相同,我想是因为它没有像它应该的那样对平均值进行分组:

    enter image description here

    如何解决此问题?

    2 回复  |  直到 1 年前
        1
  •  4
  •   Limey    1 年前

    正如我在评论中指出的,这是一个典型的非标准评估问题。这是一个修改过的函数,我相信它能满足你的需求。

    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

        2
  •  2
  •   stefan    1 年前

    将未加引号的列名传递给函数

    …需要使用拥抱运算符{{或在更复杂的情况下,使用注入运算符!!进行注入!!。

    有关更多信息,请参见例如。 this vignette .

    因此,可以通过包装使函数工作 x y 在函数内部 {{ :

    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
    )