2014-12-03 16 views
7

C'è un modo per rendere foreach() restituisce una lista nominata/data.frame. Per esempio.foreach: Mantieni nomi

foo <- list(a = 1, b = 2) 
bar <- foreach (x = foo) %do% { x * 2 } 

restituisce list(2, 4). Vorrei che restituisse list(a = 2, b = 4).

Inoltre, c'è un modo per accedere al nome all'interno del corpo del loop?

(io non sono interessato a una soluzione che assegna i nomi dopo il ciclo foreach.)

saluti

+2

Non sono sicuro che 'foreach' abbia la funzionalità per questo. Comunque puoi cambiare il tuo ciclo in 'foreach (i = seq_along (foo)) {x <- foo [[i]]; ...} 'che ti permetterà di accedere al nome di ogni elemento con' names (foo) [i] ' – konvas

+0

Puoi anche usare' x = Map (struttura, .Data = lapply (foo, list), names = names (foo)) 'per ottenere i nomi all'interno del ciclo, come se il ciclo usasse' ['invece di' [['per accedere agli elementi di' foo'. –

risposta

9

stavo usando la soluzione fino a quando ho avuto bisogno di usare un foreach nidificato (con l'operatore %:%). Sono arrivato fino a questo:

foo <- list(a = 1, b = 2) 
bar <- foreach (x = foo, .final = function(x) setNames(x, names(foo))) %do% { 
    x * 2 
    } 

Il trucco è quello di utilizzare l'argomento .final (che è una funzione applicata una volta che il risultato finale) per impostare i nomi. Questo è più bello perché non usa una variabile temporanea ed è complessivamente più pulito. Funziona con gli elenchi annidati in modo da poter conservare i nomi su più livelli della struttura.

Si noti che funziona correttamente solo se foreach ha l'argomento .inorder=T (che è l'impostazione predefinita).

3

Grazie per i vostri suggerimenti. Questo è ciò che mi si avvicinò con:

foo <- list(a = 1, b = 2) 
bar <- foreach (x = foo, n = names(foo), .combine = c) %do% { 
    rv <- list() 
    rv[[n]] <- x * 2 
    rv 
}