Bearbeiten 2019: Diese Frage wurde vor Änderungen im data.table
November 2016 gestellt. Die akzeptierte Antwort unten finden Sie sowohl für die aktuelle als auch für die vorherige Methode.
Ich habe eine data.table
Tabelle mit ungefähr 2,5 Millionen Zeilen. Es gibt zwei Spalten. Ich möchte alle Zeilen entfernen, die in beiden Spalten dupliziert sind. Früher hätte ich das für einen data.frame getan:
df -> unique(df[,c('V1', 'V2')])
aber das funktioniert nicht mit data.table. Ich habe es versucht, unique(df[,c(V1,V2), with=FALSE])
aber es scheint immer noch nur mit dem Schlüssel der data.table und nicht mit der gesamten Zeile zu funktionieren.
Irgendwelche Vorschläge?
Prost, Davy
Beispiel
>dt
V1 V2
[1,] A B
[2,] A C
[3,] A D
[4,] A B
[5,] B A
[6,] C D
[7,] C D
[8,] E F
[9,] G G
[10,] A B
In der obigen Datentabelle, in der V2
sich der Tabellenschlüssel befindet, werden nur die Zeilen 4, 7 und 10 entfernt.
> dput(dt)
structure(list(V1 = c("B", "A", "A", "A", "A", "A", "C", "C",
"E", "G"), V2 = c("A", "B", "B", "B", "C", "D", "D", "D", "F",
"G")), .Names = c("V1", "V2"), row.names = c(NA, -10L), class = c("data.table",
"data.frame"), .internal.selfref = <pointer: 0x7fb4c4804578>, sorted = "V2")
quelle
dt[, .N,by=.(V1,V2)][,1:2]
Antworten:
Für v1.9.8 + ( veröffentlicht im November 2016 )
Von
?unique.data.table
Standardmäßig werden alle Spalten verwendet (was mit übereinstimmt?unique.data.frame
)unique(dt) V1 V2 1: A B 2: A C 3: A D 4: B A 5: C D 6: E F 7: G G
Oder verwenden Sie das
by
Argument, um eindeutige Kombinationen bestimmter Spalten zu erhalten (wie zuvor für).unique(dt, by = "V2") V1 V2 1: A B 2: A C 3: A D 4: B A 5: E F 6: G G
Prior v1.9.8
Aus
?unique.data.table
ist ersichtlich, dass das Aufrufenunique
einer Datentabelle nur für den Schlüssel funktioniert. Dies bedeutet, dass Sie den Schlüssel vor dem Aufruf auf alle Spalten zurücksetzen müssenunique
.library(data.table) dt <- data.table( V1=LETTERS[c(1,1,1,1,2,3,3,5,7,1)], V2=LETTERS[c(2,3,4,2,1,4,4,6,7,2)] )
Aufruf
unique
mit einer Spalte als Schlüssel:setkey(dt, "V2") unique(dt) V1 V2 [1,] B A [2,] A B [3,] A C [4,] A D [5,] E F [6,] G G
quelle
data.table
wird nicht mehrunique()
in Schlüsseln berücksichtigt . Die Optionunique(, by = c(keys))
muss jetzt verwendet werden.Mit Ihrem Beispiel data.table ...
> dt<-data.table(V1 = c("B", "A", "A", "A", "A", "A", "C", "C", "E", "G"), V2 = c("A", "B", "B", "B", "C", "D", "D", "D", "F", "G")) > setkey(dt,V2)
Betrachten Sie die folgenden Tests:
> haskey(dt) # obviously dt has a key, since we just set it [1] TRUE > haskey(dt[,list(V1,V2)]) # ... but this is treated like a "new" table, and does not have a key [1] FALSE > haskey(dt[,.SD]) # note that this still has a key [1] TRUE
Sie können also die Spalten der Tabelle auflisten und diese dann übernehmen
unique()
, ohne den Schlüssel auf alle Spalten setzen oder löschen zu müssen (indem Sie ihn auf setzenNULL
auflisten löschen zu müssen ( ), wie es die Lösung von @Andrie erfordert (und von @MatthewDowle bearbeitet) ). Die von @Pop und @Rahul vorgeschlagenen Lösungen haben bei mir nicht funktioniert.Siehe Versuch 3 unten, der Ihrem ersten Versuch sehr ähnlich ist. Ihr Beispiel war nicht klar, deshalb bin ich mir nicht sicher, warum es nicht funktioniert hat. Es war auch vor ein paar Monaten, als Sie die Frage gepostet haben, also wurde sie vielleicht
data.table
aktualisiert?> unique(dt) # Try 1: wrong answer (missing V1=C and V2=D) V1 V2 1: B A 2: A B 3: A C 4: A D 5: E F 6: G G > dt[!duplicated(dt)] # Try 2: wrong answer (missing V1=C and V2=D) V1 V2 1: B A 2: A B 3: A C 4: A D 5: E F 6: G G > unique(dt[,list(V1,V2)]) # Try 3: correct answer; does not require modifying key V1 V2 1: B A 2: A B 3: A C 4: A D 5: C D 6: E F 7: G G > setkey(dt,NULL) > unique(dt) # Try 4: correct answer; requires key to be removed V1 V2 1: B A 2: A B 3: A C 4: A D 5: C D 6: E F 7: G G
quelle
unique(...,use.key=FALSE)
Argument helfen; jetzt als FR # 2483 abgelegt .use.key=FALSE
könnte er ignoriert werden.by=
der der Schlüssel überschrieben werden kann. Die Einstellungby=NULL
"verwendet alle Spalten und verhält sich wie die analogen data.frame-Methoden."unique(df)
arbeitet an Ihrem Beispiel.quelle
Dies sollte für Sie funktionieren
dt <- unique(dt, by = c('V1', 'V2'))
quelle
Unter Beibehaltung der data.table-Notation können Sie Folgendes verwenden:
unique(df[, .(V1, V2, V3), nomatch=0 ])
Wie hier https://stackoverflow.com/a/31875208/10087503
Ich habe die Geschwindigkeit dieser Version nicht mit der von Magma verglichen.
quelle