eindeutige Zeilen in dplyr: row_number () von tbl_dt inkonsistent zu tbl_df

8

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?

setup:

%Vor%

Ergebnis:

%Vor%

so habe ich es tatsächlich gefunden gebrochen . Ich habe gefragt:

so oder so?

Ich kann die Methode unique.data.table verwenden:

%Vor%

Ich kann summarise dann select weg vom neuen col verwenden:

%Vor%

Ich kann row_number() == 1 # FUNKTIONIERT NICHT für tbl_dt!

verwenden %Vor%

und so weiter mit den tbl_df() -Äquivalenten.

Benchmarking der entsprechenden data.table / data.frame-Methoden microbenchmark(...,times=20) :

%Vor%     
npjc 25.05.2014, 23:54
quelle

2 Antworten

7

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.

%Vor%

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 entweder fread verwenden können, um direkt eine data.table zu erhalten, oder setDT , um eine data.table zu konvertieren. als Referenz oder direkt verwenden Sie data.table(.) anstelle von data.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:

%Vor%

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:

zu nennen %Vor%     
Arun 26.05.2014, 02:12
quelle
0

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:

%Vor%

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):

%Vor%     
Alex 22.06.2016 00:10
quelle

Tags und Links