在R

时间:2016-02-02 13:39:32

标签: r function arguments ellipsis

我感兴趣的是在函数的父框架中操作省略号(...)的内容。换句话说,我想编写一个能够操作调用它的环境的函数。我怎么能这样做(即使我知道我不应该这样做)?

示例:

我有一个高级函数foo,它作为低级函数bar的包装器。在其他任务中,它反复调用bar。函数foo有两个参数;一个名为x,另一个名为y,其中y是省略号的一部分。作为一个最小的例子,想象foo如下所示。

foo <- function(x,...){
  out <- numeric(5)
  for(i in 1:5) out[i] <- bar(x,...)
  return(out)
}

注意:我无法更改foo的内容,因为它是大型R套餐的一部分;例如,我无法将省略号解压缩为类似bar.args <- list(...)的内容,并在foo内对其进行操作。这使得它变得棘手。

foo内,较低级别的函数bar负责实际的计算。此外(虽然不是它的唯一目的),它应该能够在其父帧中操纵省略号的内容,也就是说,它应该在调用时对 的运行方式进行有限的控制。多次。作为一个最小的示例,bar可能会在每次调用后增加y的值。

bar <- function(...){
  ans <- x + list(...)$y
  # change in parent frame: ...$y <- ...$y + 1
  return(ans)
}

由于bar的参数包含在省略号中,我不知道有任何好的(相对)安全的方法来执行此操作。我自己的想法是在父框架中创建一个y的副本,我可以轻松访问和修改。

bar <- function(x,...){

  # check
  chk <- mget("copyof.y", envir=parent.frame(), ifnotfound=NA)

  # change y or a copy of it
  if(is.na(chk$copyof.y)){
    ans <- x + list(...)$y
    assign("copyof.y", list(...)$y+1, pos=parent.frame())
  }else{
    ans <- x + chk$copyof.y
    assign("copyof.y", chk$copyof.y+1, pos=parent.frame())
  }

  return(ans)
}

# > foo(1,y=1)
# [1] 2 3 4 5 6

我意识到,这是R中的“坏习惯”,因为函数的关闭正在被打破,因此通常会使函数无效...但是,我无法控制foo我只能改变bar正在做的事情。换句话说,我试图欺骗 foo,允许bar对其运行方式的控制有限。

0 个答案:

没有答案