R:使用省略号参数(...)

Jan*_*ary 10 r ellipsis

我想创建一个替换一些默认参数的包装函数.

这是我正在努力解决的问题的核心:

Error in localWindow(xlim, ylim, log, asp, ...) : 
  formal argument "cex" matched by multiple actual arguments
Run Code Online (Sandbox Code Playgroud)

现在有点上下文.假设我为这样的情节定义了一个包装函数:

myplot <- function(x, ... ) {
    plot(x, cex= 1.5, ... )
}
Run Code Online (Sandbox Code Playgroud)

如果我打电话,myplot( 1:10, cex= 2 )我会得到上述错误.我知道我可以转到...清单

l <- list(...)
Run Code Online (Sandbox Code Playgroud)

然后我就能做到

if( is.null( l[["cex"]] ) ) l[["cex"]] <- 2
Run Code Online (Sandbox Code Playgroud)

但是,如何将此列表"插入"省略号参数?像(我知道这不起作用):

... <- l
Run Code Online (Sandbox Code Playgroud)

编辑:我可以在myplot定义中使用默认值(如@Thomas的答案所示),但我不想:函数接口将变得混乱.我想我可以像这样定义一个辅助函数:

 .myfunchelper <- function( x, cex= 2.0, ... ) {
   plot( x, cex= cex, ... )
 }

 myfunc <- function( x, ... ) {
    .myfunchelper( x, ... )
 }
Run Code Online (Sandbox Code Playgroud)

但是(i)它不那么优雅,(ii)不满足我的好奇心.

Tho*_*mas 14

实际答复:

你可以通过一些技巧来做到这一点.首先,像以前一样定义您的函数,但在函数内包含一个包含默认参数的列表.然后你可以解析...作为列表进入的任何参数,用任何内容替换默认值,...然后通过更新的参数列表do.call.

myplot <- function(x, ...) {
    args1 <- list(cex=4, main="Default Title") # specify defaults here
    inargs <- list(...)
    args1[names(inargs)] <- inargs
    do.call(plot, c(list(x=x), args1))
}

myplot(x=1:3) # call with default arguments
myplot(x=1:3, cex=2, main="Replacement", xlab="Test xlab") # call with optional arguments
Run Code Online (Sandbox Code Playgroud)

早期评论:

这里的问题可以通过一些示例函数看出:

myplot1 <- function(x, ... ) {
    plot(x, cex= 1.5, ... )
}

myplot2 <- function(x, cex=3, ... ) {
    plot(x, cex=cex, ... )
}

myplot3 <- function(x, ... ) {
    plot(x, ... )
}

myplot1(1:3, cex=3) # spits your error
myplot2(1:3, cex=3) # works fine
myplot3(1:3, cex=3) # works fine
Run Code Online (Sandbox Code Playgroud)

myplot2,您指定默认值cex但可以更改它.在myplot3,cex简单地通过.如果你运行myplot2两个cex参数,你会看到你的函数(myplot1)发生了什么:

myplot2(1:3, cex=3, cex=1.5) # same error as above
Run Code Online (Sandbox Code Playgroud)

所以,你可能最好避免设置任何默认值plot(),这样你就可以通过...in 传递任何东西myplot.

  • 很好的答案(谢谢!),但使用 `args1 &lt;-modifyList(args1, list(...))` 更好。因为如果“...”包含默认 args1 中不存在的一些附加参数,则“args1[names(inargs)] &lt;- inargs”将不起作用。 (2认同)