【问题标题】:How to pass alternative arguments through wrapper function?如何通过包装函数传递替代参数?
【发布时间】:2018-12-21 17:51:02
【问题描述】:

我想为两个接受可选参数的函数编写一个包装函数。

这是一个函数 fun 包装 funAfunB 的示例

funA <- function(x = 1, y = 1) return(x+y)
funB <- function(z = c(1, 1) return(sum(z))

fun <- function(x, y, z)

如果提供了xy,我希望fun 返回x+y,如果提供了向量z,则返回sum(z)

我试图查看lm 函数如何接受这些可选参数,但不清楚究竟是如何使用的,例如match.call 在这里是如何使用的。

在找到相关问题(例如How to use R's ellipsis feature when writing your own function?using substitute to get argument name with )后,我想出了一个可行的解决方案。

我的解决方案只是使用

fun <- function(...){
  inputs <- list(...)
  if (all(c("x", "y") %in% inputs){
    ans <- funA(x, y)
   } else if ("z" %in% inputs){
    ans <- funB(z)
   }

有没有更好的办法?

注意:也许这个问题可以作为重复关闭,但希望它可以用于指导其他用户找到一个好的解决方案:将我的搜索扩展到各种除了match.call之外,还包括ellipsissubstitute

【问题讨论】:

  • @agstudy 我在中途找到了一个可用的解决方案,但想知道一个更强大的方法。

标签: r


【解决方案1】:

使用missing。如果提供了xy,则返回funA(x, y);如果没有提供funB,则返回z,如果没有提供,则返回NULL

fun <- function(x, y, z) {
          if (!missing(x) && !missing(y)) {
             funA(x, y) 
          } 
          else if (!missing(z))  {
             funB(z)
          }

这似乎回答了您所说的问题,但请注意 funAfunB 中的默认参数从未使用过,所以也许您真的想要不同的东西?

请注意,问题中提供的 fun 仅在命名参数时才有效,而此处的 fun 即使按位置提供也有效。

【讨论】:

  • 我不想一定要使用默认值,我只是把它们放进去作说明(例如,一个函数需要两个数字,另一个是向量)
【解决方案2】:

例如,我想使用match.call。这与您的解决方案类似,但更强大。

fun <- function(...){
  arg <- as.list(match.call())[-1]
  f <- ifelse(length(arg)>1,"funA","funB")
  do.call(f,arg)
}

fun(x=1,y=2) ## or fun(1,2) no need to give named arguments
[1] 3
> fun(z=1:10) ## fun(1:10)
[1] 55

【讨论】:

    猜你喜欢
    • 2018-08-05
    • 1970-01-01
    • 2012-02-24
    • 2021-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-13
    • 1970-01-01
    相关资源
    最近更新 更多