Consider the example below:
> x=2
> myfun = function(y) x*y
> myfun(3)
[1] 6
> x=4
> myfun(3)
[1] 12
How would I have to define myfun
so that its definition keeps the value of x
such as it is at the time of definition, rather than a reference to x
? (ie, that the second call myfun(3)
also yields 6 rather than 12).
EDIT: changed the title to remove incorrect terminology.
I have to guess a little bit what your purpose is. Perhaps you simply need to define one of your arguments with a default value:
myfun <- function(y, x=2){
x * y
}
Then use it:
x <- 3
myfun(4)
[1] 8
myfun(x=4, 3)
[1] 12
myfun(x)
[1] 6
But perhaps you really are describing a closure.
An object is data with functions. A closure is a function with data.
--- John D Cook
Here is an example. First define a closure that remembers a snapshot:
newSnapshot <- function(x){
xx <- x
function(y) xx * y
}
Then use it:
x <- 10
myfun <- newSnapshot(x)
myfun(4)
[1] 40
x <- 4
myfun(5)
[1] 50
Almost the same question was asked on the R-help mailing list yesterday. See the discussion on Nabble for the various ways you can do that.
http://r.789695.n4.nabble.com/Force-evaluation-of-a-symbol-when-a-function-is-created-td4639350.html
And here are three ways to do it (gathered from the R-help discussion):
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)
with results
> 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
One approach is this:
myfun <- function(x = 2) {
function(y) {
x * y
}
}
Basically we write a function that returns a function that does the computation we want. In the above x
is set to 2
by default but you can vary this when you call myfun
. When we call myfun()
we save the returned function, in foo
in the example below:
> foo <- myfun()
Now, no matter what you do to x
in the global environment foo()
will always use the value of x
that was defined in the environment of myfun()
when that function was called.
> foo(3)
[1] 6
> x <- 6
> foo(3)
[1] 6
> x <- 4
> foo(3)
[1] 6
This all works because the environment of the function created by the call to myfun()
contains x
and that x
has the value of x
that was present when the function was defined.
> environment(foo)$x
[1] 2
Here's another closure solution:
myfun <- local({
x <- 2
list(
f=function(y) {
x*y
},
set.x=function(newx) {
x <<- newx
},
get.x=function() {
x
}
)
})
Then you can use it as follows:
> myfun$get.x()
[1] 2
> myfun$set.x(5)
> myfun$get.x()
[1] 5
> myfun$f(3)
[1] 15
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.