en bref:
Ich frage mich, wie man eindeutige Zeilen von einem data.table
in einem irgendwo entlang eines dplyr
-Workflows bekommt. Seit v0.2 kann ich row_number==1
( siehe: Duplikate entfernen) verwenden Zeilen mit dplyr )
ABER!
tbl_df(data) %>% group_by(Var1,Var2) %>% filter(row_number() == 1)
funktioniert.
tbl_dt(data) %>% group_by(Var1,Var2) %>% filter(row_number() == 1)
nicht. Ist das ein Fehler?
so habe ich es tatsächlich gefunden gebrochen . Ich habe gefragt:
Ich kann die Methode unique.data.table
verwenden:
Ich kann summarise
dann select
weg vom neuen col verwenden:
Ich kann row_number() == 1
# FUNKTIONIERT NICHT für tbl_dt!
und so weiter mit den tbl_df()
-Äquivalenten.
microbenchmark(...,times=20)
: Interessant. Ihre Benchmarks haben mein Interesse gespickt. Ich finde es ein bisschen komisch, dass man nicht direkt mit data.table
's unique.data.table
vergleicht. Also hier sind die Ergebnisse, indem Sie das auch auf meinem System einschließen.
Es ist 1.8x schneller als die schnellste Lösung aus all Ihren Läufen.
Erhöhen wir nun die Anzahl der eindeutigen Werte von 676 auf etwa 10.000 und sehen Sie, was passiert.
%Vor%Und hier ist es 2,6x schneller.
Hinweis: Ich plane die Erstellung von
dt
hier nicht, da Sie in realen Anwendungsfällen entwederfread
verwenden können, um direkt eine data.table zu erhalten, odersetDT
, um einedata.table
zu konvertieren. als Referenz oder direkt verwenden Siedata.table(.)
anstelle vondata.fame(.)
- was auch nicht zeitgesteuert ist.
Aber warum sind dt_u
und dt_ss
dann langsamer?
Wenn man sich die Dateien grouped-dt.r
und manip-grouped-dt.r
ansieht, geschieht dies aufgrund von 1) Kopien und 2) Setzen von Schlüsseln. (1) ist im Grunde, weil man (2) tun muss. Wenn Sie eine Zusammenfassung -Operation mit dplyr
ausführen, entspricht dies:
Ich bin mir nicht sicher, warum ad-hoc Gruppierung nicht implementiert wurde, nach dieser Diskussion unter Hadey's Antwort .
%Vor%Es werden sowohl Kopien als auch Einstellungsschlüssel vermieden.
Es ist noch schlimmer, wenn Sie mutieren . Es macht effektiv:
%Vor%Auch hier ist die Ad-hoc-Lösung einfach:
%Vor% Es werden 2 Kopien und Einstellungsschlüssel vermieden. Die einzige Kopie erfüllt die Philosophie von dplyr, Objekte nicht direkt zu verändern. Also, das wird immer langsamer + nehmen Sie den doppelten Speicher in dplyr
.
Ebenso können Kopien auf einigen Joins vermieden werden wie ich hier kommentiert habe .
Das NEWS-Element von dplyr v0.2
sagt:
- dplyr ist beim Einstellen der Schlüssel von Datentabellen vorsichtiger, so dass es niemals versehentlich ein Objekt ändert, das es nicht besitzt. Es vermeidet auch unnötige Schlüsseleinstellungen, die sich negativ auf die Leistung auswirken . (# 193, # 255).
Aber offensichtlich haben einige diskutierte Fälle es nicht geschafft.
Bisher habe ich über das Performance-Tag unter deiner Frage geschrieben. Das heißt, wenn Sie nach Leistung suchen, sollten Sie alle Fälle vermeiden, die (unnötige) Kopien (und Einstellungsschlüssel) machen, bis sie behoben sind.
In dieser Essenz, in diesem speziellen Fall, ist die beste Antwort, die ich mir vorstellen konnte, einfach unique.data.table
direkt in dplyr
ish way:
Ich bin auf dieses Problem gestoßen und habe hier eine neue Lösung gefunden, die slice
verwenden soll.
Ich habe einige zusätzliche Benchmarks in Ihrem Dataset ausgeführt, einschließlich der neuen Slice-Funktion und Ändern von dt_rn
, so dass es zuerst zu einem data.frame
wird:
Benchmarking gibt:
%Vor% In Ihrem Datensatz finde ich, dass alle Funktionen, außer dem Anwenden auf data.frame
, ungefähr die gleiche Zeit benötigen. Insbesondere finde ich keine wesentliche Steigerung der Geschwindigkeit, wie sie von Arun gefunden wird, wenn dt_direct
verwendet wird, und bemerke, dass meine Version dieser Funktion unique(..., by = ...)
aufruft.
In einer anderen Datentabelle mit 1,6 Millionen Zeilen und 28 Spalten finde ich jedoch, dass das Coercing auf eine data.frame
tatsächlich schneller ist, siehe (keine Daten bereitgestellt):
Tags und Links r performance dplyr