Uno sguardo al contesto: Molti (? La maggior parte) dei linguaggi di programmazione contemporanei in uso diffuso hanno almeno una manciata di ADT [tipi di dati astratti] in comune, in particolare,Come utilizzare correttamente gli elenchi in R?
stringa (una sequenza composta da personaggi)
lista (un insieme ordinato di valori), e
mappa basata tipo (un array non ordinato che mappa le chiavi a valori)
Nel linguaggio di programmazione R, i primi due sono implementate rispettivamente character
e vector
,.
Quando ho iniziato a imparare R, due cose erano evidenti quasi dall'inizio: list
è il più importante tipo di dati in R (perché è la classe padre per la R data.frame
), e in secondo luogo, io non riuscivo a capire come hanno funzionato, almeno non abbastanza bene da usarli correttamente nel mio codice.
Per prima cosa, è sembrato a me che tipo di dati list
di R era un'implementazione semplice della mappa ADT (dictionary
in Python, NSMutableDictionary
in Objective C, hash
in Perl e Ruby, object literal
in Javascript, e così via).
Per esempio, si creano loro solo come se fosse un dizionario Python, passando coppie chiave-valore a un costruttore (che in Python è dict
non list
):
x = list("ev1"=10, "ev2"=15, "rv"="Group 1")
E si accede ai capi di un elenco R proprio come faresti con quelli di un dizionario Python, ad es. x['ev1']
. Allo stesso modo, è possibile recuperare solo le 'chiavi' o semplicemente i 'valori' da :
names(x) # fetch just the 'keys' of an R list
# [1] "ev1" "ev2" "rv"
unlist(x) # fetch just the 'values' of an R list
# ev1 ev2 rv
# "10" "15" "Group 1"
x = list("a"=6, "b"=9, "c"=3)
sum(unlist(x))
# [1] 18
ma R list
s sono anche differenza altri ADT mappa di tipo (tra le lingue Ho imparato comunque). La mia ipotesi è che questa sia una conseguenza delle specifiche iniziali per S, cioè l'intenzione di progettare un DSL di dati/statistiche [linguaggio specifico per il dominio] da zero.
tre differenze significative tra R list
s ed i tipi di mappatura in altre lingue in uso diffuso (ad esempio ,. Python, Perl, JavaScript):
primi, list
s in R sono un ordinato collezione, proprio come i vettori, anche se i valori sono codificati (cioè, le chiavi possono essere qualsiasi valore hastable non solo interi sequenziali). Quasi sempre, il tipo di dati di mappatura in altre lingue è non ordinato.
seconda, list
s può essere restituito dalle funzioni anche se mai passato in un list
quando hai chiamato la funzione, e anche se la funzione che ha restituito il list
non contiene un (esplicito) list
costruttore (Naturalmente, si può fare con questo, in pratica, avvolgendo il risultato restituito in una chiamata a unlist
):
x = strsplit(LETTERS[1:10], "") # passing in an object of type 'character'
class(x) # returns 'list', not a vector of length 2
# [1] list
una terza caratteristica peculiare della list
s di R : è d Non sembra che possano essere membri di un altro ADT e, se provi a farlo, il contenitore primario viene forzato a list
. Per esempio,
x = c(0.5, 0.8, 0.23, list(0.5, 0.2, 0.9), recursive=TRUE)
class(x)
# [1] list
mia intenzione qui non è criticare la lingua o come viene documentato; allo stesso modo, non sto suggerendo che ci sia qualcosa di sbagliato nella struttura dei dati list
o come si comporta. Tutto quello che voglio è correggere la mia comprensione di come funzionano, così posso usarli correttamente nel mio codice.
Ecco il genere di cose che vorrei capire meglio:
Quali sono le regole che determinano quando una chiamata di funzione restituirà un
list
(ad esempio,strsplit
espressione recitato sopra)?Se non assegnare esplicitamente nomi a un
list
(ad esempio,list(10,20,30,40)
) sono i nomi predefiniti solo interi sequenziali iniziando con 1? (Presumo, ma sono tutt'altro che certo che la risposta è sì, altrimenti non saremmo in grado di forzare questo tipo dilist
ad un vettore w/una chiamata aunlist
.)Perché questi due diversi operatori,
[]
e[[]]
, restituire lo stesso risultato?x = list(1, 2, 3, 4)
entrambe le espressioni restituiscono "1":
x[1]
x[[1]]
Perché queste due espressioni non ritorno lo stesso risultato?
x = list(1, 2, 3, 4)
x2 = list(1:4)
Per favore non mi puntano alla documentazione R (?list
, R-intro
) - Ho letto con attenzione e non aiutarmi a rispondere il tipo di domande Ho recitato poco sopra.
(da ultimo, di recente ho appreso di e cominciò con un pacchetto R (disponibile sul CRAN) chiamato hash
che implementa convenzionale comportamento mappa di tipo tramite una classe S4, posso sicuramente consigliare questo pacchetto.)
Con 'x = list (1, 2, 3, 4)', entrambi non restituiscono lo stesso risultato: 'x [1]' e 'x [[1]]'. Il primo restituisce una lista e la seconda restituisce un vettore numerico. Scorrendo sotto, mi sembra che Dirk sia stato l'unico a rispondere correttamente a questa domanda. –
Non ho notato nessuno espandere il tuo elenco di modi in cui 'lista' in R non è come un hash. Ne ho un altro che penso sia degno di nota. 'list' in R può avere due membri con lo stesso nome di riferimento. Considera che 'obj <- c (list (a = 1), list (a = 2))' è valido e restituisce una lista con due valori nominati di 'a'. In questo caso, una chiamata per 'obj [" a "]' restituirà solo il primo elemento della lista corrispondente. È possibile ottenere un comportamento simile (forse identico) a un hash con un solo elemento per i nomi di riferimento che utilizzano ambienti in R., ad es. 'x <- new.env(); x [["a"]] <- 1; x [["a"]] <- 2; x [["a"]] ' – russellpierce