Devolver funciones anónimas de lapply – ¿qué está pasando mal?

Al intentar crear una lista de funciones similares utilizando lapply , encuentro que todas las funciones en la lista son idénticas e iguales a lo que debería ser el elemento final.

Considera lo siguiente:

 pow <- function(x,y) x^y pl <- lapply(1:3,function(y) function(x) pow(x,y)) pl [[1]] function (x) pow(x, y)  [[2]] function (x) pow(x, y)  [[3]] function (x) pow(x, y)  

Cuando intenta evaluar estas funciones obtiene resultados idénticos:

 pl[[1]](2) [1] 8 pl[[2]](2) [1] 8 pl[[3]](2) [1] 8 

¿Qué está pasando aquí, y cómo puedo obtener el resultado que deseo (las funciones correctas en la lista)?

R pasa promesas , no los valores en sí mismos. La promesa se impone cuando se evalúa por primera vez, no cuando se pasa, y en ese momento el índice ha cambiado si uno usa el código en la pregunta. El código se puede escribir de la siguiente manera para forzar la promesa en el momento en que se llama a la función anónima externa y dejar en claro al lector:

 pl <- lapply(1:3, function(y) { force(y); function(x) pow(x,y) } ) 

Esto ya no es cierto a partir de R 3.2.0!

La línea correspondiente en el registro de cambios dice:

Las funciones de orden superior como las funciones de aplicación y Reduce () ahora fuerzan los argumentos a las funciones que aplican para eliminar las interacciones indeseables entre la evaluación diferida y la captura de variables en los cierres.

Y de hecho:

 pow <- function(x,y) x^y pl <- lapply(1:3,function(y) function(x) pow(x,y)) pl[[1]](2) # [1] 2 pl[[2]](2) # [1] 4 pl[[3]](2) # [1] 8 
Intereting Posts