2010-10-04 10 views
5

Permítanme agregar otro problema de alcance en R, esta vez con el paquete de nevadas. Si defino una función en mi entorno global, y trato de usar que uno más tarde en un sfApply() dentro de otra función, mi primera función no se encuentra nada más:Problema de alcance cuando se usa sfApply dentro de la función (paquete de nevadas - R)

#Runnable code. Don't forget to stop the cluster with sfStop() 
require(snowfall) 
sfInit(parallel=TRUE,cpus=3) 

func1 <- function(x){ 
    y <- x+1 
    y 
} 

func2 <- function(x){ 
    y <- sfApply(x,2,function(i) func1(i)) 
    y 
} 

y <- matrix(1:10,ncol=2) 
func2(y) 
sfStop() 

Esto da:

> func2(y) 
Error in checkForRemoteErrors(val) : 
    2 nodes produced errors; first error: could not find function "func1" 

Sin embargo, si anulo mi función dentro de la otra función, funciona. También funciona cuando uso sfApply() en el entorno global. La cosa es que no quiero anidar mi función func1 dentro de esa función2, ya que eso causaría que func1 se defina muchas veces (func2 se usa en una estructura tipo bucle).

He intentado ya simplificar el código para deshacerme del doble bucle, pero eso es completamente imposible debido a la naturaleza del problema. ¿Algunas ideas?

Respuesta

4

Creo que quiere sfExport(func1), aunque no estoy seguro de si necesita hacerlo en su .GlobalEnv o dentro de func2. Esperamos que ayuda ...

> y <- matrix(1:10,ncol=2) 

> sfExport(list=list("func1")) 

> func2(y) 
    [,1] [,2] 
[1,] 2 7 
[2,] 3 8 
[3,] 4 9 
[4,] 5 10 
[5,] 6 11 
+0

en el '.GlobalEnv' es perfecto. Agregué un pequeño ejemplo. ¡Gracias! –

+0

@Joris, de nada. Lamento no haber explicado por qué necesita exportar, pero afortunadamente Dirk brindó esa información. ;-) –

2

Me parece que ahora está confundiendo de alcance con la computación paralela. Está invocando nuevas sesiones R, y es comúnmente su responsabilidad volver a crear su entorno en los nodos.

Una alternativa sería usar foreach et al. Hay ejemplos en los documentos foreach (¿o iterador?) Que muestran exactamente esto. Oh, mira, y Josh ya ha recomendado lo mismo.

+2

Solo pensé que las nevadas harían una copia del .GlobalEnv a los esclavos, cosa que no sucedió. Solo hace una copia del entorno local a los esclavos (de ahí que el código funcionó con func1 anidado en func2). Usted tiene acceso a .GlobalEnv desde dentro de sfApply. Simplemente no es el .GlobalEnv que pensé que sería ... La solución de Joshua (sfExport) y las funciones relacionadas hacen el truco. thx para la explicación –

Cuestiones relacionadas