强制函数定义评估符号

时间:2012-08-07 12:18:32

标签: r

考虑以下示例:

> x=2
> myfun = function(y) x*y
> myfun(3)
[1] 6
> x=4
> myfun(3)
[1] 12

我如何定义myfun以使其定义保持x的值,例如它在定义时,而不是x的引用? (即,第二次调用myfun(3)也产生6而不是12)。

编辑:更改标题以删除不正确的术语。

4 个答案:

答案 0 :(得分:4)

我必须猜测你的目的是什么。也许您只需要使用默认值定义一个参数:

myfun <- function(y, x=2){
  x * y
}

然后使用它:

x <- 3

myfun(4)
[1] 8

myfun(x=4, 3)
[1] 12

myfun(x)
[1] 6

但也许你真的在描述一个闭包。

  

对象是具有功能的数据。闭包是一个带数据的函数。

     

--- John D Cook

这是一个例子。首先定义一个记住快照的闭包:

newSnapshot <- function(x){
  xx <- x
  function(y) xx * y
}

然后使用它:

x <- 10
myfun <- newSnapshot(x)

myfun(4)
[1] 40

x <- 4
myfun(5)
[1] 50

答案 1 :(得分:3)

昨天在R-help邮件列表上提出了几乎相同的问题。 有关您可以采用的各种方法,请参阅有关Nabble的讨论。

http://r.789695.n4.nabble.com/Force-evaluation-of-a-symbol-when-a-function-is-created-td4639350.html

以下是三种方法(从R-help讨论中收集):

x <- 2

f1 <- local({x.now <- x;function(y) x.now*y})
f2 <- evalq(function(y)a*y,env=list(a=x))

multiply_by_x <- function(x) {
    force(x)
    function(y) y*x
}

f3 <- multiply_by_x(x)

结果

> f1(3)
[1] 6
> f2(3)
[1] 6
> f3(3)
[1] 6

> x <- 4
> f1(3)
[1] 6
> f2(3)
[1] 6
> f3(3)
[1] 6

答案 2 :(得分:2)

一种方法是:

myfun <- function(x = 2) {
    function(y) {
        x * y
    }
}

基本上我们编写一个函数,它返回一个执行我们想要的计算的函数。上述x默认设置为2,但您可以在致电myfun时更改此设置。当我们致电myfun()时,我们会在下面的示例中的foo中保存返回的函数:

> foo <- myfun()

现在,无论您在全球环境x中对foo()做了什么,x总是会使用在myfun()环境中定义的> foo(3) [1] 6 > x <- 6 > foo(3) [1] 6 > x <- 4 > foo(3) [1] 6 的值功能被称为。

myfun()

这一切都有效,因为调用x创建的函数的环境包含x,而x的值> environment(foo)$x [1] 2 在函数时出现已定义。

{{1}}

答案 3 :(得分:2)

这是另一个封闭解决方案:

myfun <- local({
  x <- 2
  list(
    f=function(y) {
      x*y
    },
    set.x=function(newx) {
      x <<- newx
    },
    get.x=function() {
      x
    }
  )
})

然后您可以按如下方式使用它:

> myfun$get.x()
[1] 2
> myfun$set.x(5)
> myfun$get.x()
[1] 5
> myfun$f(3)
[1] 15