Say I have the following function:
foo <- function(x, y = min(m)) {
m <- 1:10
x + y
}
When I run foo(1)
, the returned value is 2
, as expected. However, I cannot run foo(1, y = max(m))
and receive 11
, since lazy evaluation only works for default arguments. How can I supply an argument but have it evaluate lazily?
The simple answer is that you can't and shouldn't try to. That breaks scope and could wreak havoc if it were allowed. There are a few options that you can think about the problem differently.
first pass y as a function
foo<-function(x,y=min){
m<-1:10
x+y(m)
}
if a simple function does not work you can move m to an argument with a default.
foo<-function(x,y=min(m),m=1:10){
x+y(m)
}
Since this is a toy example I would assume that this would be too trivial. If you insist on breaking scope then you can pass it as an expression that is evaluated explicitly.
foo<-function(x,y=expression(min(m))){
m<-1:10
x+eval(y)
}
Then there is the option of returning a function from another function. And that might work for you as well, depending on your purpose.
bar<-function(f)function(x,y=f(m)){
m<-1:10
x+y
}
foo.min<-bar(min)
foo.min(1) #2
foo.max<-bar(max)
foo.max(1) #10
But now we are starting to get into the ridiculous.
My solution was to just change the default argument:
R> formals(foo)$y <- call("max", as.name("m"))
R> foo(1)
[1] 11
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With