2011-12-05 19 views
10

Tengo una función f() que tiene algunos parámetros nombrados. Llama a una función g() y quiero pasarle todos los parámetros de f. es posible?Acceda a todos los argumentos de funciones en R

Usando ... sólo cubre los argumentos adicionales:

f=function(a,callback,b,c,d,...){ 
    z=a-b 
    callback(z,...) 
    } 

g=function(z,...){ 
    print(list(...)) #Only shows $e 
    print(z) #-1 
    print(a,b,c,d) #'a' not found 
} 

f(1,g,2,3,d=4,e=5); 

pensé formales() era la respuesta, pero sólo parece ser nombres de argumentos, no sus valores!

f=function(a,callback,b,c,d,...){ 
    z=a-b 
    callback(z,formals()) 
    } 

g=function(z,...){ 
    args=list(...)[[1]] 
    print(args$a) #(no output) 
    print(class(args$a)) #"name" 
} 

f(1,g,2,3,d=4,e=5); 

¿Es posible? Gracias.

+1

Eche un vistazo al código de 'lm' y' glm' para ver cómo se hace esto. –

+0

@HongOoi Gracias; se hace con match.call (es decir, como la respuesta de Anton), aunque IIUC elige transmitir solo ciertos argumentos, no todos. –

Respuesta

15

Bueno, algo así es ciertamente posible. Debería calcular por sí mismo en qué marco/punto desea evaluar los argumentos de f que luego se envían a g.

El procedimiento típico consiste en llamar a match.call() dentro f para registrar realmente la expresión de llamada con la que se invocó f, y luego cambiar la expresión de llamada como le conviene (por ejemplo, filtrar argumentos innecesarios, agregar nuevos , etc.) y luego la evaluación de la nueva expresión de llamada a través de la llamada eval(). Por lo tanto, algo como esto debería (casi) funcionar:

f <- function(a, callback, b, c, d, ...) { 
    # Grab the "f" call expression 
    fcall <- match.call(expand.dots = FALSE) 

    # Construct the new call expression 
    fcall[[1]] <- callback 
    # Filter out/add new args 
    fcall$callback <- NULL 
    fcall$z <- z 

    # Do the call 
    eval(fcall, parent.frame()) 
} 
+0

O podría pasar usted mismo los argumentos adicionales. Mucho más fácil de entender. – hadley

+0

@hadley Sí, pero es más difícil de mantener a medida que cambia la lista de argumentos. Después de considerar todas las opciones, en mi código real busqué un argumento de lista con nombre que contenga todos los demás argumentos. Es decir. _Introduce el parámetro Object_ en la jerga de refactorización. Así que solo estoy pasando un argumento a f() y ese mismo argumento se le da a g(). –

+0

arroja un error para mí. –

Cuestiones relacionadas