2009-09-08 11 views
7

Digamos que tiene la siguiente función:La evaluación perezosa de argumentos suministrados

foo <- function(x, y = min(m)) { 
    m <- 1:10 
    x + y 
} 

Cuando corro foo(1), el valor devuelto es 2, como se esperaba. Sin embargo, no puedo ejecutar foo(1, y = max(m)) y recibir 11, ya que la evaluación diferida solo funciona para los argumentos predeterminados. ¿Cómo puedo proporcionar un argumento pero lo evalúo perezosamente?

+0

"la evaluación diferida solo funciona para los argumentos predeterminados", ¿está seguro de eso? La evaluación diferida de IIUC ocurre con todos los argumentos de función. La razón por la que su ejemplo no funciona es porque m no está en el alcance del llamante. –

Respuesta

6

La respuesta simple es que se puede y no debe intentar. Eso rompe el alcance y podría causar estragos si se lo permitiera. Hay algunas opciones para que pienses sobre el problema de manera diferente.

primera pasada y como una función

foo<-function(x,y=min){ 
m<-1:10 
x+y(m) 
} 

si una función simple no funciona se puede mover ma una discusión con un defecto.

foo<-function(x,y=min(m),m=1:10){ 
x+y(m) 
} 

Dado que este es un ejemplo de juguete, supongo que esto sería demasiado trivial. Si insiste en romper el alcance, puede pasarlo como una expresión que se evalúa explícitamente.

foo<-function(x,y=expression(min(m))){ 
m<-1:10 
x+eval(y) 
} 

Luego existe la opción de devolver una función desde otra función. Y eso podría funcionar para usted también, dependiendo de su propósito.

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 

Pero ahora estamos empezando a entrar en el ridículo.

1

Mi solución fue simplemente cambiar el argumento por defecto:

R> formals(foo)$y <- call("max", as.name("m")) 
R> foo(1) 
[1] 11 
0

Puede usar una combinación de substitute, eval.

foo <- function(x, y = min(m)) { 
    y <- substitute(y) 
    m <- 1:10 
    x + eval(y) 
} 

foo(1) 
## [1] 2 
foo(1, y = max(m)) 
## [1] 11 
Cuestiones relacionadas