2016-08-25 2 views
4

Ich versuche herauszufinden, wie Duplikate basierend auf drei Variablen entfernt werden können (id, key, and num). Ich möchte das Duplikat mit der geringsten Anzahl an gefüllten Spalten entfernen. Wenn eine gleiche Anzahl gefüllt ist, kann beides entfernt werden. Um zum Beispiel die folgenden sein würdeDuplikate entfernen, aber die vollständigste Iteration beibehalten

Original <- data.frame(id= c(1,2,2,3,3,4,5,5), 
key=c(1,2,2,3,3,4,5,5), 
num=c(1,1,1,1,1,1,1,1), 
v4= c(1,NA,5,5,NA,5,NA,7), 
v5=c(1,NA,5,5,NA,5,NA,7)) 

Der Ausgang:

Finished <- data.frame(id= c(1,2,3,4,5), 
key=c(1,2,3,4,5), 
num=c(1,1,1,1,1), 
v4= c(1,5,5,5,7), 
v5=c(1,5,5,5,7)) 

Mein richtige Datenmenge größer ist und eine Mischung aus meist numerisch, aber einige Zeichenvariablen, aber ich die beste nicht bestimmen konnte einen Weg, dies zu tun. Ich habe zuvor ein Programm verwendet, das etwas Ähnliches innerhalb des duplicates-Befehls namens check.all tun würde.

Bisher haben meine Gedanken gewesen Grepl zu verwenden und bestimmen, wo „alles“ vorhanden ist

Present <- apply(Original, 2, function(x) grepl("[[:alnum:]]", x)) 

Dann den resultierenden Datenrahmen für frage ich mit rowSums und cbind es mit dem Original.

CompleteNess <- rowSums(Present) 
cbind(Original, CompleteNess) 

Dies ist der Punkt, wo ich nicht sicher meine nächsten Schritte bin ... Ich habe eine Variable, die mir sagt, wie viele Spalten in jeder Zeile (Vollständigkeits) gefüllt sind; Ich bin mir jedoch nicht sicher, wie Duplikate implementiert werden sollen.

Einfach, ich suche nach Wenn ID, Schlüssel und Num dupliziert werden - behalten Sie die Zeile mit dem höchsten Wert von CompleteNess.

Wenn mir jemand einen besseren Weg vorstellen kann, um dies zu tun oder mich durch das letzte bisschen zu bringen, würde ich es sehr schätzen. Danke allen!

Antwort

3

hier eine Lösung. Es ist nicht sehr schön, aber es sollte für Ihre Anwendung arbeiten:

#Order by the degree of completeness  
Original<-Original[order(CompleteNess),] 

#Starting from the bottom select the not duplicated rows 
#based on the first 3 columns 
Original[!duplicated(Original[,1:3], fromLast = TRUE),] 

Diese ursprüngliche Datenrahmen paßt nicht neu anordnen so, wenn es später weitere Verarbeitung eingeschaltet ist.

2

Sie können Ihre Daten aggregieren und die Zeile mit max Punktzahl wählen:

Original <- data.frame(id= c(1,2,2,3,3,4,5,5), 
         key=c(1,2,2,3,3,4,5,5), 
         num=c(1,1,1,1,1,1,1,1), 
         v4= c(1,NA,5,5,NA,5,NA,7), 
         v5=c(1,NA,5,5,NA,5,NA,7)) 
Present <- apply(Original, 2, function(x) grepl("[[:alnum:]]", x)) 

#get the score 
Original$present <- rowSums(Present) 

#create a column to aggregate on 
Original$id.key.num <- paste(Original$id, Original$key, Original$num, sep = "-") 

library("plyr") 
#aggregate here 
Final <- ddply(Original,.(id.key.num),summarize, 
     Max = max(present)) 

Und wenn Sie die anderen Spalten halten wollen, dies nur tun:

Final <- ddply(Original,.(id.key.num),summarize, 
     Max = max(present), 
     v4 = v4[which.max(present)], 
     v5 = v5[which.max(present)] 
    ) 
Verwandte Themen