在嵌套函数中传递参数以更新默认参数

时间:2016-02-23 20:13:42

标签: r arguments

我有嵌套函数,希望将参数传递给最深的函数。最深的函数已经有默认参数,所以我将更新这些参数值。

我的mwe正在使用plot(),但实际上我正在使用png(),使用默认的高度和宽度参数。

有什么建议吗?

f1 <- function(...){ f2(...)}

f2 <- function(...){ f3(...)}

f3 <- function(...){ plot(xlab="hello1", ...)}

#this works
f1(x=1:10,y=rnorm(10),type='b')

# I want to update the default xlab value, but it fails:
f1(x=1:10,y=rnorm(10),type='b', xlab='hello2')

2 个答案:

答案 0 :(得分:7)

f3()中,"hello1"不是函数正式参数列表中xlab的默认值。它是函数体中提供的值,因此无法覆盖它:

f3 <- function(...){ plot(xlab="hello1", ...)}

我怀疑你的意思是做这样的事情。

f1 <- function(...){ f2(...)}
f2 <- function(...){ f3(...)}
f3 <- function(..., xlab="hello1") plot(..., xlab=xlab)

## Then check that it works
par(mfcol=c(1,2))
f1(x=1:10,y=rnorm(10),type='b')
f1(x=1:10,y=rnorm(10),type='b', xlab='hello2')

enter image description here

(请注意,正式参数xlab 必须遵循此处的...参数,以便它只能完全匹配(而不是部分匹配)。否则,如果没有名为xlab的参数,它将被一个名为x的参数匹配,可能(实际上在这里)会引起很多悲伤。)

答案 1 :(得分:3)

我在...中修改参数的常用方法如下:

f1 = function(...) {
  dots = list(...)
  if (!('ylab' %in% names(dots))) {
    dots$ylab = 'hello'
  }
  do.call(plot, dots)
}
# check results 
f1(x = 1:10, y = rnorm(10)) 
f1(x = 1:10, y = rnorm(10), ylab = 'hi') 

这里发生的是...在名为dots的列表中捕获。接下来,R检查此列表dots是否包含有关ylab的任何信息。如果没有信息,我们将其设置为指定值。如果有信息,我们什么都不做。最后,do.call(a, b)是一个基本上与参数a一起执行函数b的函数。

修改

这对多个默认参数更有效(并且通常也可能更好)。

f1 = function(...) {
  # capture ... in a list
  dots = list(...)
  # default arguments with their values
  def.vals = list(bty = 'n', xlab = 'hello', las = 1)
  # find elements in dots by names of def.vals. store those that are NULL
  ind = unlist(lapply(dots[names(def.vals)], is.null))
  # fill empty elements with default values 
  dots[names(def.vals)[ind]] = def.vals[ind]
  # do plot
  do.call(plot, dots)
}

f1(x = 1:10, y = rnorm(10), ylab = 'hi', bty = 'l')