Wann sollte ich den Operator: = in data.table verwenden?

87

data.tableObjekte haben jetzt den Operator: =. Was unterscheidet diesen Operator von allen anderen Zuweisungsoperatoren? Was sind ihre Verwendungszwecke, wie viel schneller ist es und wann sollte es vermieden werden?

Ari B. Friedman
quelle

Antworten:

93

Hier ist ein Beispiel, das 10 Minuten auf 1 Sekunde reduziert zeigt (von NEWS auf der Homepage ). Es ist so, als würde man eine Unterzuweisung vornehmen, kopiert data.framejedoch nicht jedes Mal die gesamte Tabelle.

m = matrix(1,nrow=100000,ncol=100)
DF = as.data.frame(m)
DT = as.data.table(m)

system.time(for (i in 1:1000) DF[i,1] <- i)
     user  system elapsed 
  287.062 302.627 591.984 

system.time(for (i in 1:1000) DT[i,V1:=i])
     user  system elapsed 
    1.148   0.000   1.158     ( 511 times faster )

Putting die :=in jso mehr Idiome erlaubt:

DT["a",done:=TRUE]   # binary search for group 'a' and set a flag
DT[,newcol:=42]      # add a new column by reference (no copy of existing data)
DT[,col:=NULL]       # remove a column by reference

und :

DT[,newcol:=sum(v),by=group]  # like a fast transform() by group

Ich kann mir keine Gründe vorstellen, die ich vermeiden sollte :=! Anders als innerhalb einer forSchleife. Da es :=im Inneren erscheint DT[...], kommt es mit dem geringen Aufwand der [.data.tableMethode; zB S3 Versand und Überprüfung auf das Vorhandensein und die Art der Argumente wie i, by, nomatchusw. Also für Innere forSchleifen gibt es einen geringen Overhead, direkte Version :=genannt set. Sehen Sie ?setfür weitere Informationen und Beispiele. Die Nachteile von setinclude imüssen Zeilennummern sein (keine binäre Suche) und Sie können sie nicht mit kombinieren by. Durch diese Einschränkungen setkann der Overhead drastisch reduziert werden.

system.time(for (i in 1:1000) set(DT,i,"V1",i))
     user  system elapsed 
    0.016   0.000   0.018
Matt Dowle
quelle
26
Vielen Dank für die Entwicklung dieses Pakets. Ich habe das Gefühl, dass ich einen Großteil meines Codes überarbeiten werde, um dieses Paket zu verwenden.
Iterator
1
Im Chat wurde ich gebeten, mich selbst zu fragen / zu beantworten (was anscheinend empfohlen wird ) - diese Frage ist hier
Matt Dowle
4
@MatthewDowle Möchten Sie eine Erklärung hinzufügen, wann Sie nicht verwenden sollten: = und stattdessen set () verwenden?
Ari B. Friedman
2
@MatthewDowle Ich würde wieder +1, wenn ich könnte.
Ari B. Friedman
3
@jabberwocky Kein Problem. set(DT, i, "V1", i)Legt die "V1"Spalte fest, während set(DT, i, colVar, i)der in der colVarVariablen enthaltene Spaltenname festgelegt wird (z. B. wenn colVar = "V1"dies früher geschehen ist). Die Anführungszeichen geben an, dass der Spaltenname wörtlich genommen werden soll, anstatt die Variable nachzuschlagen.
Matt Dowle