【问题标题】:Use to 2 parameters ... in one function在一个函数中使用 2 个参数 ...
【发布时间】:2015-10-26 13:35:37
【问题描述】:

我知道问题的标题听起来很傻,但我想创建一个函数test_f,它可以使用test_f 中使用的函数的多个参数(我使用了最新版本的ggplot2 和新函数aes_) . 例如

devtools::install_github('hadley/scales')
devtools::install_github('hadley/ggplot2')

test <- function(data,x,y,...){
  ggplot(data, aes_(substitute(x), substitute(y)))+
    geom_point(...)+
    scale_y_continuous(...)
}

什么时候

test(mtcars, qsec, mpg,limit = c(1,100))

一切正常,但是

test(mtcars, qsec, mpg,size = 5)

显示错误:Error in scale_y_continuous: Unused parameter (size = 5)

我知道为什么会这样,但我想知道是否可以将... 用于多个内部函数,而不是像下面那样将所有参数放入test_f

test <- function(data,x,y,..., size = 5, limit = c(1,100){
   ...
   ...
}

【问题讨论】:

  • 不,...不会作为参数传递,你必须指定你想要的。如果您希望它可以更改,只需将大小和限制添加为另一个参数(具有一些默认值),因此如果您不更改它们,它们仍然可以工作

标签: r function ggplot2


【解决方案1】:

可能值得一提的是使用一个或两个列表来包装可选参数的替代策略。借用另一个答案,

mygg <- function(data, x, y, 
                 geom_pars = list(), 
                 scale_pars = list()) {

  p <- ggplot(data=data, aes_(substitute(x), substitute(y)))
  g <- do.call(geom_point, geom_pars)
  s <- do.call(scale_y_continuous, scale_pars)

  p + list(g, s)

}

调用函数有点冗长,但通常不那么令人困惑,因为我们明确了参数应该去哪里。

mygg(mtcars, mpg, wt)

mygg(mtcars, mpg, wt, geom_pars=list(color="blue"))

mygg(mtcars, mpg, wt, scale_pars=list(limits=c(3,4)))

mygg(mtcars, mpg, wt, 
    geom_pars=list(fill="green", color="blue", shape=21), 
    scale_pars=list(limits=c(3,4)))

【讨论】:

    【解决方案2】:

    你可以,但这取决于接收函数如何处理事情:

    f2 <- function(three, ...) {
    
      g <- as.list(match.call())
    
      print(sprintf("three (from named args) = %d", three))
    
      if ("five" %in% names(g)) print(sprintf("five (from ...) = %d", g$five))
    
    }
    
    f1 <- function(x, y, ...) {
    
      if (missing(x)) stop("x is missing", call.=FALSE)
      if (missing(y)) stop("y is missing", call.=FALSE)
    
      g <- as.list(match.call())
    
      print(sprintf("x = %d", x))
      print(sprintf("y = %d", y))
    
      f2(...)  
    
    }
    
    f1(1, 2, three=4, five=6)
    ## [1] "x = 1"
    ## [1] "y = 2"
    ## [1] "three (from named args) = 4"
    ## [1] "five (from ...) = 6"
    

    由于您遇到的问题是 scale_y_continuous(因此是 continuous_scale)抱怨未使用的参数,因此您只能传入它将从 ... 列表中接受的内容。这意味着您的职能需要一些内部工作,但这绝对是可行的:

    mygg <- function(data, x, y, ...) {
    
      gg <- ggplot(data=data, aes_(substitute(x), substitute(y)))
    
      # get what geom_point accepts
      geom_point_aes <- c("x", "y", "alpha", "colour", "color", "fill", "shape", "size", "stroke")
      point_params <- unique(c(geom_point_aes, 
                               names(formals(geom_point)), 
                               names(formals(layer))))
    
      # get what scale_y_continuous accepts
      scale_y_params <- unique(c(names(formals(scale_y_continuous)), 
                                 names(formals(continuous_scale))))
    
      # get all ... params passed in (if any)
      args <- list(...)
    
      if (length(args) > 0) {
    
        # get all the arg names
        arg_names <- names(args)
    
        # which ones are left for point
        gg <- gg + do.call(geom_point, 
                           sapply(intersect(arg_names, point_params), 
                                  function(x) { list(args[[x]]) }))
    
        # which ones are left for scale_y
        gg <- gg + do.call(scale_y_continuous, 
                           sapply(intersect(arg_names, scale_y_params), 
                                  function(x) { list(args[[x]]) }))
    
      } else {
    
        gg <- gg + geom_point() + scale_y_continuous()
    
      }
    
      return(gg)
    
    }
    

    我不会用 png 来混淆答案,但是如果您运行以下命令,您应该会看到修改后的函数做了什么。

    mygg(mtcars, mpg, wt)
    
    mygg(mtcars, mpg, wt, color="blue")
    
    mygg(mtcars, mpg, wt, limits=c(3,4))
    
    mygg(mtcars, mpg, wt, fill="green", color="blue", shape=21, limits=c(3,4), left="over")
    

    【讨论】:

    • 哇。伟大的!真的很感激!
    猜你喜欢
    • 2020-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-13
    相关资源
    最近更新 更多