data.table versucht möglichts wenige Kopien zu machen, da es auf große Datenmengen ausgelegt ist.
Angenommen ich hätte eine data.frame der 80% meines RAMs füllt, dann wäre ein Kopie i) vermutlich nicht möglich (zu wenig Platz und ii) unnötige Zeitverschwendung.
Das ist bei R data.frame etwas ungünstig (R macht bei data.frame z.b. mindestens eine Kopie wenn maN etwas am data.frame ändert).
Wenn du ':=' verwendest um eine Spalte einzufügen, hängt data.table die einfach an. data.frame hingegen kopieren zuerstmal den ganzen data.frame...
Stichwort ' by reference '...
Ähnlich ist es bei '<-': data.table macht hier keine volle Kopie, sondern nur einen verweise / link / reference (wie du es auch nennen willst).
Möchtest du eine volle Kopie haben musst du copy() benutzen.
Hier ein Beispiel, welches den Speicherverbrauch zeigt und andeutet was data.table macht und warum es nicht das tut was du meinst dass es tun sollte:
Code: Alles auswählen
rm(list = ls())
library(data.table)
library(pryr)
# some data ---------------------------------------------------------------
df1 <- mtcars
# repeat data to make it bigger
df1 <- do.call("rbind", replicate(100000, df1, simplify = FALSE))
# set data.table
setDT(df1)
# add col
df1[ , m_gear := gear / mean(gear)]
# space occupied
object_size(df1) # 307 MB
# this is a copy by reference (= do not copy full object, only the reference)
mem_change(df2 <- df1) # 660 B (= nothing copied at all)
df2 <- df1
# this is a full object copy
mem_change(df3 <- copy(df1)) # 307 MB (=full size of df1 copied)
df3 <- copy(df1)
# this changes only df3 (= full copy, no reference to df1)
df3[ , m_gear := NULL]
# this changes df2 AND df1, as both point to the same reference
df2[ , m_gear := NULL]
Hoffe das hilft und veranschaulicht es.
Siehe auch ?copy und ?data.table.
BTW: Deine Erzeugung der neuen Spalte verbraucht in deiner version (neues Objekt im workspace erstellen und dann zuweisen) wesentlich mehr speicher und ist langsamer im vergleich zum Einzeiler (!). - Das ist die Power von data.table!