2016-10-11 13 views
0

Ich habe einen Datensatz von 300k + Fällen und wo eine Kundennummer mehrmals wiederholt werden kann. Jedem Kunden ist ein Datum und ein Rang zugeordnet. Ich möchte in der Lage sein, nur eindeutige Kunden-IDs nach Datum sortiert zu halten. Wenn es eine doppelte ID mit einem doppelten Datum gibt, würde sie nach Rang sortieren (wobei der Rang 1 am nächsten steht). Ein Beispiel für meine Daten ist wie folgt:Entfernen von Duplikaten basierend auf 3 Spalten in R

Customer.ID Date  Rank 
576293  8/13/2012 2 
576293  11/16/2015 6 
581252  11/22/2013 4 
581252  11/16/2011 6 
581252  1/4/2016  5 
581600  1/12/2015 3 
581600  1/12/2015 2 
582560  4/13/2016 1 
591674  3/21/2012 6 
586334  3/30/2014 1 

Ideal Ergebnis würde dann so aussehen:

Customer.ID Date  Rank 
576293  11/16/2015 6 
581252  1/4/2016  5 
581600  1/12/2015 2 
582560  4/13/2016 1 
591674  3/21/2012 6 
586334  3/30/2014 1 
+0

Scheint, wie Sie sollten nur sortieren Sie Ihre Daten und Verwende dann 'unique()' oder 'duplicated()', um duplizierte IDs zu entfernen. – MrFlick

+0

Es wäre besser, wenn Sie Probendaten nach 'dput'-Funktion bereitstellen können. –

+0

Ihr Ergebnis hat keine eindeutigen Kundennummern –

Antwort

1

Mit dem gewünschten Ausgang des OP geklärt:

Wir auch dies tun können, mit Base R, die schneller als die unten dplyr Ansatz mit group_by(Customer.ID) Ansatz sein wird, da wir nicht über alle einzigartigen Customer.ID:

durchlaufen müssen

Hinweise:

  1. Zuerst sortiert nach Customer.ID aufsteigend nach Date gefolgt, um von Rank aufsteigend gefolgt absteigend.
  2. Entfernen Sie die Duplikate in Customer.ID, so dass nur die erste Zeile für jede Customer.ID gehalten wird.

Das Ergebnis Ihrer gesendeten Daten als Datenrahmen mit df (ohne die Date Spalte Umwandlung) in aufsteigender Reihenfolge für Customer.ID:

print(res) 
## Customer.ID  Date Rank 
##2  576293 11/16/2015 6 
##5  581252 1/4/2016 5 
##7  581600 1/12/2015 2 
##8  582560 4/13/2016 1 
##10  586334 3/30/2014 1 
##9  591674 3/21/2012 6 

Daten:

df <- structure(list(Customer.ID = c(591674L, 586334L, 582560L, 581600L, 
581252L, 576293L), Date = c("3/21/2012", "3/30/2014", "4/13/2016", 
"1/12/2015", "1/4/2016", "11/16/2015"), Rank = c(6L, 1L, 1L, 
2L, 5L, 6L)), .Names = c("Customer.ID", "Date", "Rank"), row.names = c(9L, 
10L, 8L, 7L, 5L, 2L), class = "data.frame") 

Wenn Sie nur die neuesten d behalten möchten Zeile ate (von niedrigerem Rang gefolgt) für jeden Customer.ID, können Sie die folgenden Aktionen mit dplyr:

library(dplyr) 
res <- df %>% group_by(Customer.ID) %>% arrange(desc(Date),Rank) %>% 
       summarise_all(funs(first)) %>% 
       ungroup() %>% arrange(Customer.ID) 

Hinweisen:

  1. group_byCustomer.ID und sortieren arrange durch Date mit Ordnung und Rank von aufsteigend in absteigend Auftrag.
  2. summarise_all, um nur die erste Zeile von jedem Customer.ID zu behalten.
  3. Schließlich ungroup und sortieren nach Customer.ID, um Ihr gewünschtes Ergebnis zu erhalten.

Verwenden Sie Ihre Daten als Datenrahmen df mit der Date Spalte in die Date Klasse umgewandelt:

print(res) 
### A tibble: 7 x 3 
## Customer.ID  Date Rank 
##  <int>  <date> <int> 
##1  576293 2015-11-16  6 
##2  581252 2016-01-04  5 
##3  581600 2015-01-12  2 
##4  582560 2016-04-13  1 
##5  586334 2014-03-30  1 
##6  591674 2012-03-21  6 

Daten:

df <- structure(list(Customer.ID = c(576293L, 576293L, 581252L, 581252L, 
581252L, 581600L, 581600L, 582560L, 591674L, 586334L), Date = structure(c(15565, 
16755, 16031, 15294, 16804, 16447, 16447, 16904, 15420, 16159 
), class = "Date"), Rank = c(2L, 6L, 4L, 6L, 5L, 3L, 2L, 1L, 
6L, 1L)), .Names = c("Customer.ID", "Date", "Rank"), row.names = c(NA, 
-10L), class = "data.frame") 
+0

Das hat mich dahin gebracht. Der schwierige Teil war, dass ich das Datum absteigend und aufsteigend absteigend brauchte. Da ich nicht in der Lage war, herauszufinden, wie man mehrere Wege gleichzeitig sortiert, rekodierte ich den Rang in der entgegengesetzten Richtung (also 1 = 6, 2 = 5 usw.). Dann funktionierte dein Code großartig. Vielen Dank! –

+0

@ J.Gorman: der Code, den ich gepostet habe, sollte das für Sie tun, ohne 'Rank' rekodieren zu müssen, wenn' Rank' numerisch ist. Dies liegt daran, dass '-df $ Rank' mit' sinking = TRUE' in 'order' verwendet wird. Beachten Sie, dass wir 'sinking = TRUE' in' order' verwenden müssen, da '-as.Date (...)' nicht funktioniert. – aichao

Verwandte Themen