traumatismo sufre sabor que por perdida olor olfato mayor llama gusto gripe enfermedades como causas adulto r

sufre - Extraño comportamiento mapply: ¿Qué me he perdido?



perdida olor y sabor (2)

Este es el resultado de una evaluación perezosa: todos los argumentos se transmiten por el árbol de llamadas como promesas para evitar la ejecución innecesaria y permanecen en este estado suspendido hasta que R esté convencido de que se utilizan.

En su código, simplemente rellena las funciones con la misma promesa para una y la misma promesa para b; entonces todos se comprometieron con un último par de vales. Como @Tommy ya mostró, la solución es forzar el compromiso "utilizando" el valor antes de que se defina la función.

El siguiente código no funciona como esperaba:

a <- list(0, 1) b <- list(0, 1) # return a linear function with slope `a` and intercept `b`. f <- function(a, b) function(x) a*x + b # create a list of functions with different parameters. fs <- mapply(f, a, b) # test fs[[1]](3) # [1] 4 # expected zero! fs[[2]](3) # [1] 4

puede alguien decirme por que?

NB: He encontrado una solución alternativa, por lo que no estoy buscando una forma diferente de lograr el resultado deseado. Pero tengo curiosidad por saber por qué este enfoque en particular no funcionó.

Actualizar:

A partir de R 3.2.0, esto ahora funciona como se esperaba:

a <- list(0, 1) b <- list(0, 1) f <- function(a, b) function(x) a*x + b fs <- mapply(f, a, b) # test fs[[1]](3) # [1] 0 fs[[2]](3) # [1] 4


[Actualización] Mi análisis inicial fue correcto, pero las conclusiones fueron erróneas :) Llegemos a las conclusiones después del análisis.

Aquí hay un código que demuestra los efectos:

x <- lapply(1:3, function(x) sys.frame(sys.nframe())) x[[1]] # An environment x[[2]] # Another environment x[[3]] # Yet nother environment x[[1]]$x # 3!!! (should be 1) x[[2]]$x # 3!! (should be 2) x[[3]]$x # 3 as expected # Accessing the variable within the function will "fix" the weird behavior: x <- lapply(1:3, function(x) {x; sys.frame(sys.nframe())}) x[[1]]$x # 1 x[[2]]$x # 2 x[[3]]$x # 3

Así que el trabajo en su caso:

f <- function(a, b) { a;b; function(x) a*x + b }

Por cierto, como @James observa, hay una función de force que hace que el acceso a una variable sea más explícito:

f <- function(a, b) { force(a);force(b); function(x) a*x + b }

Conclusiones

Bueno, como anotaron @mbq y @hadley, esto se debe a una evaluación perezosa. Es más fácil de mostrar con un simple bucle for:

fs <- list(); for(i in 1:2) fs[[i]] <- f(a[[i]], b[[i]])

El argumento de la función f ''s x no obtendrá el valor de a[[i]] (que es 0 ), sino toda la expresión y el entorno en el que existen ayi. Cuando accede a x , se evalúa y, por lo tanto, utiliza la i en el momento de la evaluación. Si el for-loop se ha movido desde la llamada a f , obtienes el resultado "incorrecto" ...

Inicialmente dije que esto se debía a un error en *apply , que no lo es. ... pero como odio estar equivocado, puedo señalar que * aplicar SÍ tiene un error (o quizás más de una inconsistencia) en estos casos:

lapply(11:12, function(x) sys.call()) #[[1]] #FUN(11:12[[1L]], ...) # #[[2]] #FUN(11:12[[2L]], ...) lapply(11:12, function(x) function() x)[[1]]() # 12 lapply(11:12, function(x) function() x)[[2]]() # 12

Como se ve arriba, el código lapply dice que llama a la función con 11:12[[1L]] . Si evalúas eso "más tarde" , aún deberías obtener el valor 11 , ¡pero en realidad obtendrás 12 !

Esto probablemente se deba al hecho de que lapply se implementa en código C por razones de rendimiento y hace trampa un poco, por lo que la expresión que muestra no es la expresión que se evalúa, ergo, un error ...

QED