.EACHI in data.table?

Non riesco a trovare alcuna documentazione su cosa esattamente. .EACHI fa in data.table . Ne vedo una breve menzione nella documentazione:

L’aggregazione per un sottogruppo di gruppi noti è particolarmente efficiente quando si passa a quei gruppi in i e si imposta by=.EACHI . Quando i è un data.table, DT[i,j,by=.EACHI] valuta j per i gruppi di DT cui ogni riga in i unisce. Chiamiamo questo raggruppamento da ciascun i.

Ma cosa significa “gruppi” nel contesto di DT ? Un gruppo è determinato dal tasto impostato su DT ? Il gruppo è una riga distinta che utilizza tutte le colonne come chiave? Comprendo perfettamente come eseguire qualcosa come DT[i,j,by=my_grouping_variable] ma sono confuso su come .EACHI avrebbe funzionato. Qualcuno potrebbe spiegare per favore?

Ho aggiunto questo alla lista qui . E speriamo di essere in grado di consegnare come pianificato.


La ragione è molto probabile che by=.EACHI sia una funzionalità recente (dal 1.9.4), ma ciò che fa non lo è . Lasciatemi spiegare con un esempio. Supponiamo di avere due data.tables X e Y :

 X = data.table(x = c(1,1,1,2,2,5,6), y = 1:7, key = "x") Y = data.table(x = c(2,6), z = letters[2:1], key = "x") 

Sappiamo che possiamo partecipare facendo X[Y] . è simile a un’operazione sottoinsieme , ma utilizza data.tables (invece di interi / nomi di riga o valori logici). Per ogni riga in Y , prendendo le colonne chiave di Y , trova e restituisce corrispondenti righe corrispondenti nelle colonne chiave di X (+ colonne in Y ).

 X[Y] # xyz # 1: 2 4 b # 2: 2 5 b # 3: 6 7 a 

Ora diciamo che ci piacerebbe, per ogni riga delle colonne chiave di Y (qui solo una colonna chiave), vorremmo ottenere il conteggio delle corrispondenze in X Nelle versioni di data.table <1.9.4 , possiamo farlo semplicemente specificando .N in j come segue:

 # < 1.9.4 X[Y, .N] # x N # 1: 2 2 # 2: 6 1 

Ciò che fa implicitamente è, in presenza di j , valutare l' j-expression su ogni risultato corrispondente di X (corrispondente alla riga in Y ). Questo è stato chiamato by-without-by o implicito , perché è come se ci fosse un nascosto.

Il problema era che questo eseguirà sempre un'operazione by operazione. Quindi, se volessimo conoscere il numero di righe dopo un join, allora dovremmo fare: X[Y][ .N] (o semplicemente nrow(X[Y]) in questo caso). Cioè, non possiamo avere l'espressione j nella stessa chiamata se non vogliamo un by-without-by . Di conseguenza, quando abbiamo fatto per esempio X[Y, list(z)] , ha valutato la list(z) usando by-without-by ed era quindi leggermente più lento.

Inoltre, data.table utenti di data.table hanno richiesto che fosse esplicito : vedere questo e questo per più contesto.

Quindi by=.EACHI stato aggiunto. Ora, quando lo facciamo:

 X[Y, .N] # [1] 3 

fa ciò che è destinato a fare (evita la confusione). Restituisce il numero di righe risultanti dal join.

E,

 X[Y, .N, by=.EACHI] 

valuta j -expression sulle righe corrispondenti per ogni riga in Y (corrispondente al valore delle colonne chiave di Y qui). Sarebbe più semplice vederlo usando which=TRUE .

 X[.(2), which=TRUE] # [1] 4 5 X[.(6), which=TRUE] # [1] 7 

Se eseguiamo. N per ciascuno, allora dovremmo ottenere 2,1.

 X[Y, .N, by=.EACHI] # x N # 1: 2 2 # 2: 6 1 

Quindi ora abbiamo entrambe le funzionalità. Spero che questo ti aiuti.