2010-11-12 11 views
7

Supongamos que tenemos una lista (mylist) que se utiliza como objeto de entrada para una función lapply. ¿Hay alguna manera de saber qué elemento en mylist se está evaluando? El método debería funcionar en lapply y snowfall::sfApply (y otros posibles miembros de la familia también).qué elemento de lista se está procesando cuando se utiliza nevadas :: sfLapply?

En chat, Gavin Simpson sugirió el siguiente método. Esto funciona muy bien para lapply pero no tanto para sfApply. Me gustaría evitar paquetes adicionales o jugar con la lista. ¿Alguna sugerencia?

mylist <- list(a = 1:10, b = 1:10) 
foo <- function(x) { 
    deparse(substitute(x)) 
} 
bar <- lapply(mylist, FUN = foo) 

> bar 
$a 
[1] "X[[1L]]" 

$b 
[1] "X[[2L]]" 

Esta es la versión paralela que no lo está cortando.

library(snowfall) 
sfInit(parallel = TRUE, cpus = 2, type = "SOCK") # I use 2 cores 

sfExport("foo", "mylist") 
bar.para <- sfLapply(x = mylist, fun = foo) 

> bar.para 
$a 
[1] "X[[1L]]" 

$b 
[1] "X[[1L]]" 

sfStop() 

Respuesta

3

Creo que vas a tener que usar la solución/sugerencia de Shane en esa sesión de chat. Almacenar sus objetos en una lista de tal manera que cada componente de la lista de arriba contiene un componente con el nombre o identificación o un experimento que figura en dicho componente de lista, además de un componente que contiene el objeto que desea procesar:

obj <- list(list(ID = 1, obj = 1:10), list(ID = 2, obj = 1:10), 
      list(ID = 3, obj = 1:10), list(ID = 4, obj = 1:10), 
      list(ID = 5, obj = 1:10)) 

Por lo tanto, tienen la siguiente estructura:

> str(obj) 
List of 5 
$ :List of 2 
    ..$ ID : num 1 
    ..$ obj: int [1:10] 1 2 3 4 5 6 7 8 9 10 
$ :List of 2 
    ..$ ID : num 2 
    ..$ obj: int [1:10] 1 2 3 4 5 6 7 8 9 10 
$ :List of 2 
    ..$ ID : num 3 
    ..$ obj: int [1:10] 1 2 3 4 5 6 7 8 9 10 
$ :List of 2 
    ..$ ID : num 4 
    ..$ obj: int [1:10] 1 2 3 4 5 6 7 8 9 10 
$ :List of 2 
    ..$ ID : num 5 
    ..$ obj: int [1:10] 1 2 3 4 5 6 7 8 9 10 

el tiene algo así como la primera línea en la siguiente función, seguido de su

foo <- function(x) { 
    writeLines(paste("Processing Component:", x$ID)) 
    sum(x$obj) 
} 

Qué hará haz esto:

> res <- lapply(obj, foo) 
Processing Component: 1 
Processing Component: 2 
Processing Component: 3 
Processing Component: 4 
Processing Component: 5 

Que podría funcionar en la nieve.

2

También podría modificar los atributos como tal.

mylist <- list(a = 1:10, b = 1:10) 
attr(mylist[[1]], "seq") <- 1 
attr(mylist[[2]], "seq") <- 2 

foo <- function(x) { 
    writeLines(paste("Processing Component:", attributes(x))) 
} 
bar <- lapply(mylist, FUN = foo) 

(y la versión paralela)

mylist <- list(a = 1:10, b = 1:10) 
attr(mylist[[1]], "seq") <- 1 
attr(mylist[[2]], "seq") <- 2 

foo <- function(x) { 
    x <- paste("Processing Component:", attributes(x)) 
} 
sfExport("mylist", "foo") 
bar <- sfLapply(mylist, fun = foo) 
+0

que parecía "mal" y, efectivamente, cuando intento 'attr (milista [[1]]) <- 1', me sale:' Error en 'attr <-' (' * tmp * ', value = 2): 2 argumentos pasados ​​a 'attr <-' que requiere 3'. Creo que debe especificar un nombre para el atributo –

+0

@BondedDust gracioso, no recuerdo que este no funcione. Edité las dos líneas ofensivas. –

Cuestiones relacionadas