2012-06-25 4 views
6

Ho notato alcuni comportamenti inconsistenti (incoerenti) in data.table quando si utilizzano operatori di assegnazione diversi. Devo ammettere che non ho mai avuto la differenza tra "=" e copy(), quindi forse potremmo fare un po 'di luce qui. Se si utilizza "=" o "< -" invece di copy() di seguito, dopo aver modificato data.table copiato, anche la data.table originale cambierà.data.table 1.8.1 .: "DT1 = DT2" non è uguale a DT1 = copia (DT2)?

Si prega di eseguire i seguenti comandi e vedrete cosa intendo

library(data.table) 
example(data.table) 

DT 
    x y v 
1: a 1 42 
2: a 3 42 
3: a 6 42 
4: b 1 4 
5: b 3 5 
6: b 6 6 
7: c 1 7 
8: c 3 8 
9: c 6 9 

DT2 = DT 

ora cambierò il v colonna DT2:

DT2[ ,v:=3L] 
    x y v 
1: a 1 3 
2: a 3 3 
3: a 6 3 
4: b 1 3 
5: b 3 3 
6: b 6 3 
7: c 1 3 
8: c 3 3 
9: c 6 3 

ma guarda cosa è successo a DT:

DT 
    x y v 
1: a 1 3 
2: a 3 3 
3: a 6 3 
4: b 1 3 
5: b 3 3 
6: b 6 3 
7: c 1 3 
8: c 3 3 
9: c 6 3 

modificato anche. così: cambiare DT2 ha cambiato il DT originale. non così se uso copy():

example(data.table) # reset DT 
DT3 <- copy(DT) 
DT3[, v:= 3L] 
    x y v 
1: a 1 3 
2: a 3 3 
3: a 6 3 
4: b 1 3 
5: b 3 3 
6: b 6 3 
7: c 1 3 
8: c 3 3 
9: c 6 3 

DT 
    x y v 
1: a 1 42 
2: a 3 42 
3: a 6 42 
4: b 1 4 
5: b 3 5 
6: b 6 6 
7: c 1 7 
8: c 3 8 
9: c 6 9 

questo comportamento è previsto?

risposta

10

Sì. Questo è un comportamento previsto e ben documentato.

Poiché data.table utilizza i riferimenti all'oggetto originale per ottenere la modifica sul posto, è molto veloce.

Per questo motivo, se si davvero desidera copiare i dati, è necessario utilizzare copy(DT)


Dalla documentazione per ?copy:

Il data.table viene modificato da riferimento, e restituito (invisibilmente) così può essere usato in dichiarazioni composte; ad es., setkey(DT,a)[J("foo")]. Se è necessaria una copia, prendere prima una copia (utilizzando DT2=copy(DT)). copy() può anche essere utile prima che := venga utilizzato per il riassegnazione di un numero a una colonna per riferimento. Vedi ?copy.

Vedi anche questa domanda: Understanding exactly when a data.table is a reference to vs a copy of another

+0

Grazie @Andrie. Comprendo l'assegnazione per riferimento e perché evitare di copiare in primo luogo. Mi sembra strano che '=' crei un collegamento tra la copia e l'originale, come se fossero lo stesso oggetto (quando non è il caso in R altrimenti). –

+0

@FlorianOswald Sono d'accordo: questa può essere una trappola se non si presta attenzione. – Andrie

+1

+10 se potessi Andrie. @ Florian Immagina una tabella da 20 GB + in memoria. Non vogliamo assolutamente copiarlo, neanche una volta. Ma se lo vuoi davvero, puoi farlo. Non rompe la compatibilità con altri pacchetti, perché è solo ': =' e le funzioni 'set *' che assegnano per riferimento. È uno dei motivi per cui abbiamo introdotto un nuovo operatore (': ='), piuttosto che rendere '<-' un lavoro diverso. –

Problemi correlati