2016-07-29 3 views
2

Ich muss Duplikate aus einem großen Datenrahmen entfernen, der 100 Millionen Zeilen hat. Ich teste, ob data.table mir dabei helfen kann. Im folgenden Code hat unique() in data.table jedoch nicht das gleiche Ergebnis wie unique() für data.frame generiert. Gibt es einen möglichen Fehler im setkey in data.table?Unique in data.table fiel versehentlich ein Wert

library(data.table) 
tmp <- data.frame(id=c(1000000128152, 1000000228976, 1000000235508, 1000000294933, 1000000311288, 1000000353770, 1000000441585, 1000000466482, 1000000473521, 
         1000000491353, 1000000497787, 1000000534948, 1000000589071, 1000000622890, 1000000658287, 1000000695865, 1000000731674, 1000000780659, 
         1000000818218, 1000000834389, 1000000877189, 1000000937770, 1000000937770, 1000000996135, 1000001061831, 1000001062057, 1000001065241, 
         1000001097542, 1000001122242, 1000001177167, 1000001194078, 1000001216323, 10000, 1000001294998, 1000001361126, 1000001361126, 
         1000001389830, 1000001411284, 1000001415793, 1000001417557, 1000001485326, 1000001565513, 1000001624601, 1000001650282, 1000001681805, 
         1000001683548, 1000001683548, 1000001693445, 1000001693455, 1000001693462, 1000001693466, 1000001693490, 1000001693490, 1000001703493, 
         1000001703511, 1000001703518, 1000001703546, 1000001703554, 1000001703613, 1000001703644)) 
unique(tmp$id) 
DT <- data.table(tmp) 
setkey(DT, id) 
DTU <- unique(DT) 
DTU$id 

Results from the unique(tmp$id): 
[1] 1000000128152 1000000228976 1000000235508 1000000294933 1000000311288 1000000353770 1000000441585 1000000466482 1000000473521 1000000491353 1000000497787 1000000534948 
[13] 1000000589071 1000000622890 1000000658287 1000000695865 1000000731674 1000000780659 1000000818218 1000000834389 1000000877189 1000000937770 1000000996135 1000001061831 
[25] 1000001062057 1000001065241 1000001097542 1000001122242 1000001177167 1000001194078 1000001216323 10000
[37] 1000001415793 1000001417557 1000001485326 1000001565513 1000001624601 1000001650282 1000001681805 1000001683548 1000001693445 1000001693455 1000001693462 1000001693466 
[49] 1000001693490 1000001703493 1000001703511 1000001703518 1000001703546 1000001703554 1000001703613 1000001703644 

Result from DTU$id: 
[1] 1000000128152 1000000228976 1000000235508 1000000294933 1000000311288 1000000353770 1000000441585 1000000466482 1000000473521 1000000491353 1000000497787 1000000534948 
[13] 1000000589071 1000000622890 1000000658287 1000000695865 1000000731674 1000000780659 1000000818218 1000000834389 1000000877189 1000000937770 1000000996135 1000001061831 
[25] 1000001062057 1000001065241 1000001097542 1000001122242 1000001177167 1000001194078 1000001216323 10000
[37] 1000001415793 1000001417557 1000001485326 1000001565513 1000001624601 1000001650282 1000001681805 1000001683548 1000001693445 1000001693455 1000001693462 1000001693490 
[49] 1000001703493 1000001703511 1000001703518 1000001703546 1000001703554 1000001703613 1000001703644 

Vergleichen wir die beiden, sehen wir, dass 1000001693466 versehentlich in DTU fallen gelassen wurde. Irgendwelche Vorschläge warum? Ich vermute, es ist der Setkey, denn wenn ich die 1000000000000 von allen Zahlen subtrahiert habe, ist das Ergebnis dasselbe.

+0

tmp ist nur eine Teilmenge von der große Datenrahmen und hat nur 60 Werte. – smz

+0

Das sieht für mich wie ein Gleitkommafehler aus. Versuchen Sie vielleicht, eine Spalte zu erstellen, die "id" in ein Zeichenformat umwandelt, und führen Sie dann einen eindeutigen Aufruf aus? – rosscova

+1

Sie passen in der neuesten Version des Pakets zusammen. Wenn Sie darüber nachlesen möchten, warum, könnte diese jüngste Antwort eines der Autoren des Pakets ein guter Anfang sein: http://stackoverflow.com/a/37628905/ Möglicherweise gibt es eine bessere Referenz; Wenn ja, bin ich sicher, dass jemand später darauf hinweisen wird. – Frank

Antwort

8

Bearbeiten (von Arun): Die Standard-Rundungsfunktion wurde in der current development version of data.table, v1.9.7 entfernt und wird wahrscheinlich so weitergehen. Anweisungen zur Installation finden Sie unter here.

Dies bedeutet auch, dass Sie für das Verständnis der Einschränkungen bei der Darstellung von Fließkommazahlen und dem Umgang damit verantwortlich sind :-).


help(setkey) sagt (data.table version 1.9.6):

Hinweis, die Spalten mit numerischen Typen (dh doppelt) haben ihre letzten beiden Bytes während der Berechnung, um standardmäßig abgerundet, unerwartetes Verhalten zu vermeiden, aufgrund zu Einschränkungen bei der genauen Darstellung von Gleitkommazahlen. Werfen Sie einen Blick auf setNumericRounding, um mehr zu erfahren.

Durch Verändern auf 1 Byte Rundung vor

DT <- data.table(tmp) 
setNumericRounding(1) # set rounding 
setkey(DT, id) 

der Wert nicht länger Keying wird fallen gelassen werden.

Jedoch sagt help(setNumericRounding)

Für große Zahlen (ganze Zahlen> 2^31), wir bit64 empfehlen :: Integer64 anstatt Einstellung Rundung 0

+0

Das funktioniert. Vielen Dank! Meine Daten.Tabelle ist immer noch 1.9.6. Ich werde herausfinden, wie man bit64 :: integer64 verwendet. – smz

+1

Danke für deine Bearbeitung, @Arun. War nicht bewusst, dass dies entfernt wurde, müssen so schnell wie möglich auf die neueste Version von "1.9.7" aktualisieren. Danke auch für den zusätzlichen Service, der den Link zu den Installationsanweisungen liefert. Großartige Arbeit, die du machst, BTW. – Uwe

+0

@UweBlock danke! – Arun