2010-11-12 4 views
7

Si supponga di avere un elenco (mylist) che viene utilizzato come oggetto di input per una funzione lapply. C'è un modo per sapere quale elemento di mylist è in fase di valutazione? Il metodo dovrebbe funzionare su lapply e snowfall::sfApply (e altri possibili applicare i membri della famiglia).quale elemento della lista viene elaborato quando si usa snowfall :: sfLapply?

Su chat, Gavin Simpson ha suggerito il seguente metodo. Funziona alla grande per lapply ma non così tanto per sfApply. Vorrei evitare pacchetti extra o giocherellare con la lista. Eventuali suggerimenti?

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]]" 

Questa è la versione parallela che non la sta tagliando.

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() 

risposta

3

Penso che dovremo usare la soluzione/suggerimento di Shane in quella sessione di chat. Memorizza i tuoi oggetti in una lista in modo tale che ogni componente della top list contiene un componente con il nome o l'ID o esperimento contenuta in tale componente lista, oltre a un componente che contiene l'oggetto che si desidera elaborare:

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)) 

Così abbiamo avere la seguente struttura:

> 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 

l'hanno qualcosa come la prima linea nella seguente funzione, seguito dal vostro

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

che sarà A questo scopo:

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

Che potrebbe funzionare sulle nevicate.

2

Potrei anche modificare gli attributi in questo modo.

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) 

(e la versione parallela)

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

che sembrava "sbagliato" e abbastanza sicuro, quando provo 'attr (mylist [[1]]) <- 1', ottengo:' Errore in 'attr <-' (' * tmp * ', valore = 2): 2 argomenti passati a 'attr <-' che richiede 3'. Penso che sia necessario specificare un nome per l'attributo –

+0

@BondedDust divertente, non ricordo che questo NON funzioni. Ho modificato le due righe offensive. –