Ricerca…


introduzione

La chiave e gli indici di un data.table consentono a determinati calcoli di funzionare più velocemente, principalmente in relazione a join e sottoinsiemi. La chiave descrive l'ordinamento corrente della tabella; mentre ogni indice memorizza le informazioni sull'ordine della tabella rispetto a una sequenza di colonne. Vedere la sezione "Osservazioni" sotto per i collegamenti alle vignette ufficiali sull'argomento.

Osservazioni

Le vignette ufficiali sono la migliore introduzione a questo argomento:

Chiavi contro indici

Un data.table può essere "digitato" da una sequenza di colonne, indicando le funzioni interessate che i dati sono ordinati da tali colonne. Per ottenere o impostare la chiave, utilizzare le funzioni documentate al ?key

Allo stesso modo, le funzioni possono trarre vantaggio dagli "indici" di data.table. Ogni indice e una tabella possono avere più di uno: memorizza le informazioni sull'ordine dei dati rispetto a una sequenza di colonne. Come una chiave, un indice può accelerare determinati compiti. Per ottenere o impostare indici, utilizzare le funzioni documentate in ?indices .

Gli indici possono anche essere impostati automaticamente (attualmente solo per una singola colonna alla volta). Vedi ?datatable.optimize per i dettagli su come funziona e su come disabilitarlo se necessario.

Verifica e aggiornamento

I valori mancanti sono consentiti in una colonna chiave.

Le chiavi e gli indici sono memorizzati come attributi e potrebbero, per errore, non corrispondere all'ordine effettivo dei dati nella tabella. Molte funzioni verificano la validità della chiave o dell'indice prima di usarlo, ma vale la pena tenerlo a mente.

Le chiavi e gli indici vengono rimossi dopo gli aggiornamenti, laddove non è ovvio che l'ordinamento sia preservato. Ad esempio, a partire da DT = data.table(a=c(1,2,4), key="a") , se aggiorniamo come DT[2, a := 3] , la chiave è rotta.

Miglioramento delle prestazioni per la selezione di sottoinsiemi

# example data
set.seed(1)
n  = 1e7
ng = 1e4
DT = data.table(
    g1  = sample(ng, n, replace=TRUE),
    g2  = sample(ng, n, replace=TRUE),
    v  = rnorm(n)
)

Corrispondenza su una colonna

Dopo la prima esecuzione di un'operazione di subsetting con == o %in% ...

system.time(
    DT[ g1 %in% 1:100]
)
#    user  system elapsed 
#    0.12    0.03    0.16 

Un indice è stato creato automaticamente per g1 . Le successive operazioni di subsetting avvengono quasi istantaneamente:

system.time(
    DT[ g1 %in% 1:100]
)
#    user  system elapsed 
#       0       0       0

Per monitorare quando viene creato o utilizzato un indice, aggiungere l'opzione verbose=TRUE o modificare le options(datatable.verbose=TRUE) impostazione globale options(datatable.verbose=TRUE) .

Corrispondenza su più colonne

Attualmente, la corrispondenza su due colonne non crea automaticamente un indice:

system.time(
    DT[ g1 %in% 1:100 & g2 %in% 1:100]
)
#    user  system elapsed 
#    0.57    0.00    0.57

Rieseguire questo e rimarrà lento. Anche se aggiungiamo manualmente l'indice con setindex(DT, g1, g2) , rimarrà lento perché questa query non è ancora ottimizzata dal pacchetto.

Fortunatamente, se possiamo enumerare le combinazioni di valori che vogliamo cercare e un indice è disponibile, possiamo equi-join rapidamente:

system.time(
    DT[ CJ(g1 = 1:100, g2 = 1:100, unique=TRUE), on=.(g1, g2), nomatch=0]
)
#    user  system elapsed 
#    0.53    0.00    0.54 
setindex(DT, g1, g2)
system.time(
    DT[ CJ(g1 = 1:100, g2 = 1:100, unique=TRUE), on=.(g1, g2), nomatch=0]
)
#    user  system elapsed 
#       0       0       0

Con CJ , è importante prestare attenzione al numero di combinazioni che diventano troppo grandi.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow