2013-07-24 15 views
25

C'è un modo per utilizzare mapply su due vettori per costruire una lista nominata? Il primo vettore sarà di tipo character e contiene i nomi utilizzati per l'elenco mentre il secondo contiene i valori.Creazione di una lista con nome da due vettori (nomi, valori)

Finora, l'unica soluzione che ho è:

> dummyList = list() 
> addToList <- function(name, value) { 
+ dummyList[[name]] <- value 
+ } 
> mapply(addToList, c("foo", "bar"), as.list(c(1, 2)) 
$foo 
`1` 

$bar 
`2` 

Questa sembra una soluzione piuttosto artificioso, ma non riesco a capire come farlo in altro modo. I problemi che ho con esso sono:

  1. Si richiede la creazione di dummyList anche se dummyList non è mai cambiato, ed è una lista vuota dopo la chiamata a mapply.

  2. Se il vettore numerico, c(1, 2), non viene convertito in un elenco, il risultato della chiamata a mapply è un vettore denominato di doppio.

Per aggirare il problema 2, posso sempre chiamare mapply su due vettori e quindi chiamare as.list sul risultato, ma sembra che ci dovrebbe essere un modo per creare direttamente una lista con i valori essere in un vettore.

risposta

46

È possibile utilizzare setNames()

setNames(as.list(c(1,2)), c("foo", "bar")) 

(per una lista) o

setNames(c(1,2), c("foo", "bar")) 

(per un vettore)

+2

Grazie. Non ero a conoscenza della funzione 'setNames' e si adatta perfettamente ai miei obiettivi. Per curiosità, c'è un modo per farlo usando 'lapply' di cui sei a conoscenza? Sembra possibile che 'lapply' possa restituire liste. –

+0

cosa intendi con "usare' lapply' "? Vuoi eseguire la stessa operazione usando 'lapply'? (Se sì, perché? Come esercizio di programmazione? Più contesto sarebbe utile.) Se vuoi fare qualcos'altro, modifica la tua domanda o chiedi a una nuova? –

8

Condivido perplessità di Ben sul perché si potrebbe desiderare di fare questo, e la sua raccomandazione.

Solo per curiosità, c'è una sorta di funzione "nascosta" in mapply che permetterà questo:

x <- letters[1:2] 
y <- 1:2 
mapply(function(x,y) { y }, x, y, SIMPLIFY = FALSE,USE.NAMES = TRUE) 
$a 
[1] 1 

$b 
[1] 2 

Notando che la documentazione per USE.NAMES dice:

USE.NAMES logica ; usa i nomi se il primo argomento ha nomi, oppure se è un vettore di caratteri, usa quel vettore di caratteri come nome.

+1

Non penso che questo sia un caso d'uso così sconcertante, solo uno degenerato. Avevo bisogno di combinare due doppi array ognuno con una sorta di colonna row.names che non veniva automaticamente rilevata da USE.NAMES, quindi dovevo passare manualmente row.names (x) come argomento alla funzione che non si può usare: 'f = function (n, x, y) {if (y> 0) {-1 * x} else {x}}; r = mapply (f, row.names (x), x, y, SIMPLIFY = F, USE.NAMES = T) '. Un 'data.frame (unlist (r))' ha completato il lavoro. Grazie per aver segnalato questa funzione! –