代码之家  ›  专栏  ›  技术社区  ›  Indrajeet Patil

不管参数是否有圆括号,都能使函数工作

  •  1
  • Indrajeet Patil  · 技术社区  · 6 年前

    我正在围绕某个包中的函数编写一个包装函数。该函数基本上为 ggplot 物体。但是,按照函数的实现方式,需要将主题参数指定为函数。但是我希望我的包装器函数能够工作,而不管参数是指定为函数还是主题对象。我该怎么做?

    下面是函数的一个玩具示例,它工作的条件和不工作的条件:

    # loading needed libraries
    library(ggplot2)
    
    # creating basic plot on which themes are to be added
    plot <- ggplot(mtcars, aes(wt, mpg)) + geom_point()
    
    # first attempt at the function
    theme_adder1 <- function(ggplot.obj, ggtheme = ggplot2::theme_bw) {
      # this can't be modified (because it was written by someone else)
      ggplot.obj + ggtheme() 
    }
    
    # this works
    theme_adder1(ggplot.obj = plot, ggtheme = ggplot2::theme_grey)
    

    # this doesn't work
    theme_adder1(ggplot.obj = plot, ggtheme = ggplot2::theme_grey())
    #> Error in ggtheme(): could not find function "ggtheme"
    
    # checking classes
    class(ggplot2::theme_bw())
    #> [1] "theme" "gg"
    class(ggplot2::theme_bw)
    #> [1] "function"
    

    ggtheme theme function 对象,然后使用。但我不知道怎么做。

    # second attempt at modifying function in a way that it will work irrespective
    # of how the ggtheme argument is entered
    theme_adder2 <- function(ggplot.obj, ggtheme = ggplot2::theme_bw) {
      if (class(ggtheme)[[1]] == "function") {
        ggplot.obj + ggtheme()
      } else if (class(ggtheme)[[1]] == "theme") {
        # what modifcation can be made here?
        ggtheme <- ??? 
        ggplot.obj + ggtheme()
      }
    }
    

    创建日期:2018-08-28 reprex package (v0.2.0.9000)。

    1 回复  |  直到 6 年前
        1
  •  2
  •   zack    6 年前

    试试这个:

    theme_adder2 <- function(ggplot.obj, ggtheme = ggplot2::theme_bw) {
      if (class(ggtheme)[[1]] == "function") {
        ggplot.obj + ggtheme()
      } else if (class(ggtheme)[[1]] == "theme") {
        # what modifcation can be made here?
          ggplot.obj + eval(ggtheme)
      }
    }
    

    ggtheme 没有 eval() ...

    theme_adder2 <- function(ggplot.obj, ggtheme = ggplot2::theme_bw) {
      if (class(ggtheme)[[1]] == "function") {
        ggplot.obj + ggtheme()
      } else if (class(ggtheme)[[1]] == "theme") {
        # what modifcation can be made here?
          ggplot.obj + ggtheme
      }
    }