R函数中的默认参数(形式参数由多个实际参数匹配)

Ste*_*ner 7 r function argument-passing

简单的问题,我希望.我想编写一个绘图函数,如果用户没有指定,则该函数具有y轴标签的默认值.我还想允许...其他绘图参数的参数,并允许用户ylab手动设置.但我无法弄清楚如何做到这一点.

# simple scatterplot function with a default ylab
scatter <- function(x,y, ...) {
    plot(x, y, ylab="Default y-axis label", ...)
}

# generate data
x <- rnorm(100)
y <- x+rnorm(100)

# use the default
scatter(x,y)

# here I want to use my own label, but I get an error!
scatter(x, y, ylab="New y-axis label")
Run Code Online (Sandbox Code Playgroud)

我得到的错误是:

Error in plot.default(x, y, ylab = "Default y-axis label", ...) : 
  formal argument "ylab" matched by multiple actual arguments 
Run Code Online (Sandbox Code Playgroud)

我理解这个问题,但我不知道修复它的最佳方法.谢谢您的帮助!

编辑:我意识到我可以做类似的事情

scatter <- function(x,y,ylab = "Default y-axis label", ...) {
    plot(x, y, ylab= ylab, ...)
}
Run Code Online (Sandbox Code Playgroud)

...但是如果我正在写一个提交给CRAN的软件包,并且我有很多我想要操作的默认选项,我不想记录所有这些标准的绘图参数,因为它们被使用了在我的函数定义中.

jor*_*ran 10

尝试这样做:

scatter <- function(x,y,ylab = "Default y-axis label", ...) {
    plot(x, y, ylab= ylab, ...)
}
Run Code Online (Sandbox Code Playgroud)

在Arun的回答中稍微扩展一下,如果您有很多参数,这是一条路线的草图:

def_args <- list(ylab = "Default Label",xlab = "Default Label")

scatter <- function(x,y, ...) {
    cl <- as.list(match.call())[-1L]
    do.call("plot",c(cl,def_args[!names(def_args) %in% names(cl)]))
}
Run Code Online (Sandbox Code Playgroud)

需要一些思考来决定如何处理参数的部分匹配(如果有的话).例如,可能是这样的:

scatter <- function(x,y, ...) {
    cl <- as.list(match.call())[-1L]
    names(cl) <- match.arg(names(cl),
                           names(formals(plot.default)),several.ok = TRUE)
    do.call("plot",c(cl,def_args[!names(def_args) %in% names(cl)]))
}
Run Code Online (Sandbox Code Playgroud)

将处理参数的部分匹配.


Aru*_*run 5

match.call用于检查是否ylab已指定为参数的一种方法:

scatter <- function(x,y, ...) {
    mcall = as.list(match.call())[-1L]
    if (!"ylab" %in% names(mcall))
        plot(x, y, ylab="Default y-axis label", ...)
    else plot(x, y, ...)
}
Run Code Online (Sandbox Code Playgroud)

正如评论中提到的list(...)那样,获得扩展的点数参数比获得所有正式参数更好match.call.

您也可以尝试使用pmatch而不是%in%部分匹配参数.