1

考虑下面的例子:

> 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

4 回答 4

4

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

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

然后使用它:

x <- 3

myfun(4)
[1] 8

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

myfun(x)
[1] 6

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

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

--- 约翰·D·库克

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

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

然后使用它:

x <- 10
myfun <- newSnapshot(x)

myfun(4)
[1] 40

x <- 4
myfun(5)
[1] 50
于 2012-08-07T12:26:49.587 回答
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
于 2012-08-07T13:04:38.067 回答
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()containsx并且在定义函数时存在x该值。x

> environment(foo)$x
[1] 2
于 2012-08-07T13:06:10.513 回答
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
于 2012-08-07T13:16:48.197 回答