Bin ich etwas falsch also tun sollte ich .SD
zugunsten einzelner Spalten zu vermeiden?
Ja, genau. Verwenden Sie nur .SD
, wenn Sie wirklich alle Daten innerhalb .SD
verwenden. Sie können auch feststellen, dass der Anruf an nrow()
und der Unterabfrage an [.data.table
innerhalb j
auch Schuldige sind: Verwenden Sie Rprof
, um zu bestätigen.
Siehe die letzten Sätze von FAQ 2.1:
FAQ 2.1 Wie kann ich einen wirklich langen Ausdruck j vermeiden zu schreiben? Sie haben gesagt, ich sollte die Spaltennamen verwenden, aber ich habe viele Spalten.
Wenn die Gruppierung, die j
Ausdruck Spaltennamen als Variablen verwenden können, wie Sie wissen, es kann aber auch ein Symbol reserviert .SD
, die für jede Gruppe den Subset des Data.table bezieht sich verwenden (ohne die Gruppierung Spalten). Also, um alle Ihre Spalten zusammenzufassen, ist es nur DT[,lapply(.SD,sum),by=grp]
. Es mag schwierig erscheinen, aber es ist schnell zu schreiben und schnell zu laufen. Beachten Sie, dass Sie keine anonyme Funktion erstellen müssen. Sehen Sie die Timing-Vignette und Wiki für den Vergleich mit anderen Methoden . Das Objekt .SD
wird effizient intern implementiert und mehr als ein Argument an eine Funktion übergeben. Bitte tun Sie dies nicht though: DT[,sum(.SD[,"sales",with=FALSE]),by=grp]
. Das funktioniert aber ist sehr ineffizient und unelegant. Dies ist, was beabsichtigt war: DT[,sum(sales),by=grp]
und könnte 100-mal schneller sein.
Auch die erste Kugel von häufig gestellten Fragen 3.1:
FAQ 3.1 Ich habe 20 Spalten und eine große Anzahl von Zeilen. Warum ist ein Ausdruck einer Spalte so schnell?
Mehrere Gründe:
- Nur die Spalte gruppiert ist, werden die anderen 19 ignoriert, weil data.table
die j
Ausdruck prüft und erkennt es nicht die anderen Spalten zu verwenden ist.
Wenn data.table
inspiziert j
und sieht das .SD
Symbol, geht der Effizienzgewinn aus dem Fenster. Es muss die gesamte Untergruppe .SD
für jede Gruppe auffüllen, auch wenn Sie nicht alle Spalten verwenden. Es ist sehr schwierig für data.table
zu wissen, welche Spalten von .SD
Sie wirklich verwenden (j
könnte if
s enthalten, zum Beispiel). Allerdings, wenn Sie sie alle sowieso brauchen, ist es natürlich egal, wie in DT[,lapply(.SD,sum),by=...]
. Das ist die ideale Verwendung von .SD
.
Also, ja, vermeiden Sie .SD
, wo immer es möglich ist. Verwenden Sie die Spaltennamen direkt, um der optimierung von data.table j
die beste chance zu geben. Die bloße Existenz des Symbols .SD
in j
ist wichtig.
Deshalb wurde .SDcols
eingeführt. So können Sie sagen, data.table
welche Spalten sollten in .SD
sein, wenn Sie nur eine Teilmenge möchten. Andernfalls wird data.table
.SD
mit allen Spalten füllen, nur für den Fall j
braucht sie.
Vielen Dank! Ich wurde mit dem Satz "Das .SD-Objekt ist effizient intern implementiert und effizienter als die Übergabe eines Arguments an eine Funktion" ausgetrickst und verstand nicht das "Bitte tue das nicht though: DT [, sum (.SD [," sales ", mit = FALSE]), by = grp]" aufgrund von with = FALSE. Das wird meinen Code beschleunigen! – vsalmendra
@vsalmendra Ah, ja, es könnte klarer sein. Es ist eine Sache, die in der Vergangenheit der Gemeinschaftsdiskussion überlassen wurde. Letztendlich hoffen wir, die "j" -Optimierung zu verbessern, so dass Benutzer solche Dinge nicht mehr wissen müssen. –
@vsalmendra Ich habe jetzt FAQ 2.1 für die nächste Version verbessert. –