eindeutige Zeilen in dplyr : row_number() von tbl_dt inkonsistent, tbl_df
en bref:
Frage ich mich, wie man einzigartige Zeilen aus einer data.table
im irgendwo entlang einer dplyr
workflow. Seit v0.2, die ich verwenden kann row_number==1
(finden Sie unter: Entfernen Sie doppelte 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 bug?
setup:
library(dplyr)
library(data.table)
library(microbenchmark)
little <- expand.grid(rep(letters,121),rep(letters,121)) # my 10M row dataset.
tbl_dt(little) %>% group_by(Var1,Var2) %>% filter(row_number() == 1)
Ergebnis:
> Error in rank(x, ties.method = "first") :
> argument "x" is missing, with no default
dies ist, wie ich eigentlich fand, dass es gebrochen. Ich wurde gefragt:
so oder so?
Ich kann die unique.data.table
Methode:
dt_u <- function() {
tbl_dt(little) %>%
group_by(Var1,Var2) %>%
unique(.) %>%
tbl_dt(.) }
Kann ich verwenden summarise
dann select
Weg der neuen col:
dt_ss <- function() {
tbl_dt(little) %>%
group_by(Var1,Var2) %>%
summarise( n = n() ) %>%
select( -(n) ) }
Kann ich verwenden row_number() == 1
# FUNKTIONIERT NICHT für tbl_dt!
dt_rn <- function() {
tbl_dt(little) %>%
group_by(Var1,Var2) %>%
filter( row_number() == 1 ) }
und so weiter mit der tbl_df()
- äquivalente.
benchmarking die entsprechenden Daten.Tabelle /Daten.frame Methoden microbenchmark(...,times=20)
:
> Unit: milliseconds
> expr min lq median uq max neval
> dt_ss() 579.0385 618.0002 661.9056 694.0705 764.2221 20
> dt_u() 690.1284 729.8723 756.5505 783.7379 897.4799 20
> df_ss() 419.7841 436.9871 448.1717 461.7023 523.2798 20
> df_u() 3971.1699 4044.3663 4097.9848 4168.3468 4245.8346 20
> df_rn() 646.1497 687.3472 711.3924 724.6235 754.3166 20
- Bitte die Datei eine minimale reproduzierbare Beispiel bei github.com/hadley/dplyr/issues
- es sieht aus wie das Problem wurde protokolliert (und landete schließlich) in github.com/hadley/dtplyr/issues/23
Du musst angemeldet sein, um einen Kommentar abzugeben.
Interessant. Deine benchmarks Spike mein Interesse. Ich finde es etwas merkwürdig, dass man Sie nicht vergleichen, gegen
data.table
'sunique.data.table
direkt. So, hier sind die Ergebnisse, indem Sie diese als gut auf meinem system.Es ist 1,8 x schneller als die Schnellste Lösung von allen Ihren Läufen.
Nun vergrößern wir die Anzahl der eindeutigen Werte aus 676 bis etwa 10.000 und sehen, was passiert.
- Und hier, es ist 2,6 x schneller.
Aber warum sind beide
dt_u
unddt_ss
langsamer dann?Suchen Sie in der Datei
grouped-dt.r
undmanip-grouped-dt.r
dies geschieht, weil der 1) kopiert und 2) einstelltasten. (1) ist im Grunde, weil der mit zu tun (2). Wenn Sie eine zusammenfassen Betrieb mitdplyr
, es ist äquivalent zu:Ich bin mir nicht sicher, warum ad-hoc - Gruppierung wurde nicht umgesetzt, nachdem diese Diskussion unter Hadey Antwort.
Vermeidet es sowohl Kopien als auch setting-Taste.
Ist es sogar noch schlimmer, wenn Sie mutieren. Es ist effektiv zu tun:
Hier nochmal die ad-hoc-Lösung ist einfach:
Vermeidet es 2 Kopien und das festlegen der Schlüssel.. Die nur kopieren gibt es zu Genüge dplyr-Philosophie nicht ändern von Objekten im Ort. So, das wird immer langsamer + unter bis zweimal die Speicher in
dplyr
.Ebenso Kopien auf einige joins können vermieden werden wie ich schon hier kommentiert.
Die NACHRICHT aus
dplyr v0.2
sagt:Aber klar geraumer diskutierten Fällen nicht gemacht haben, es.
Bisher schrieb ich über die performance-tag unter Ihrer Frage. Das ist, wenn Sie für die Leistung, die Sie sollten vermeiden, alle Fälle, die macht (überflüssige) Kopien (und-Einstellung-Tasten), bis es behoben ist.
In diesem Wesen, in diesem speziellen Fall die beste Antwort, die ich konnte, ist einfach nur rufen Sie
unique.data.table
direkt indplyr
ish Weg:tbl_dt
Geschmack lässtdata.table
Methoden safe + es ist code lesbar für nicht-erfahrene / breiteste Publikum, das ist mir wichtig. Das sagte ich auch wollen, um sicherzustellen, ich bin mit diesen tools richtig/effizient auf meine mem-data-size.unique.data.table
gerade weil ich versuche zu verstehen, die Auswirkungen dergroup_by()
"Einstellung acitons" undtbl_dt()
"Nötigung " Aktionen". Das ist genau das, was Sie erklärt haben und damit das Häkchen, danke.Ich lief in dieses problem, und eine neue Lösung gefunden hier, die
slice
.Ich lief einige zusätzliche benchmarks, die auf Ihrem dataset, einschließlich die neue slice-Funktion und ändern
dt_rn
so dass es zwingt zu einerdata.frame
erste:Benchmarking gibt:
Auf Ihre Daten legen-ich finde, dass alle Funktionen, außer für die Nötigung zu einer
data.frame
dauert ungefähr die gleiche Zeit. Insbesondere habe ich nicht die deutliche Steigerungen in der Geschwindigkeit, wie die von Arun bei der Verwendungdt_direct
dem Hinweis, dass meine version von diese Funktion ruftunique(..., by = ...)
.Jedoch auf einem anderen Daten-Tabelle mit 1,6 Millionen Zeilen und 28 Spalten, ich finde, dass die Nötigung zu einer
data.frame
ist tatsächlich schneller, siehe (keine Daten vorhanden):