2016-06-22 10 views
0

Ich muss Duplikate aus einem Datensatz löschen. Mein Problem ist, dass sobald ich die Daten sortiere und die Duplikate markiere (unter Verwendung der Verzögerungsfunktion), einige Informationen über Variablen innerhalb der doppelten Beobachtung und einige innerhalb der ursprünglichen Beobachtung vorhanden sind. Ich muss Informationen über alle Variablen behalten und gleichzeitig die Duplikate löschen.SAS: Umgang mit Duplikaten, ohne variable Informationen zu verlieren

Mein Gedanke war, zuerst alle Informationen zwischen dem Original und dem Duplikat zu füllen, bevor das Duplikat gelöscht wurde.

Beispiel von Beobachtungen nach Daten und das Markieren von Duplikaten (gefälschte Datenwerte) Sortierung:

Province AGE BRTHYEAR Trans_id Morb_id VarX flag_duplicate 
AB  36 1980  45654  .   .   0 
AB  36 1980   .  .  2135   1 
ON  26 1990   .  .  8868   0 
ON  26 1990   .  35464  8868   1 

Was ich will:

Province AGE BRTHYEAR Trans_id Morb_id VarX flag_duplicate 
AB  36  1980  45654  .  2135   0 
AB  36  1980  45654  .  2135   1 
ON  26  1990   .  35464  8868   0 
ON  26  1990   .  35464  8868   1 

So kann ich Duplikate löschen und schließlich haben diese:

Province AGE BRTHYEAR Trans_id Morb_id VarX flag_duplicate 
AB   36  1980  45654  .  2135   0 
ON   26  1990   .  35464  8868   0 

Ich habe Lag und Lead-Variablen erstellt, um zu versuchen, Informationen auszufüllen, aber es wird nur angezeigt ms, um an einem Teil des Datensatzes zu arbeiten. Hier

ist der Code für die Lead-Variablen:

data uncleaned_data; 
merge uncleaned_data 
    uncleaned_data(
    firstobs=2 
    keep= TRANS_ID MORB_ID Varx 
    rename=(TRANS_ID=lead_TRANS_ID MORB_ID=lead_MORB_ID Varx=lead_Varx)); 

if lag(flag_duplicate=1) then do; 

    if TRANS_ID=. then do; 
    TRANS_ID= lead_TRANS_ID; 
    end; 

if MORB_ID=. then do; 
    MORB_ID= lead_MORB_ID; 
    end; 

if Varx=. then do; 
    Varx= lead_Varx; 
    end; 

end; 
run; 

Ich habe die gleiche Art der Sache für Verzögerung Variablen außer meinem ersten if-Anweisung ist ‚wenn flag_duplicate = 1, dann tun;‘

Diese Methode scheint nicht für viele doppelte Paare in meinem Datensatz zu funktionieren.

Gibt es eine bessere Möglichkeit, mein Problem insgesamt anzugehen? möglicherweise durch proc SQL?

Vielen Dank für das Lesen und einen Ratschlag angeboten!

Antwort

1

Ich gehe davon aus, dass Sie nicht verschiedene Werte von TRANS_ID verfügen, zum Beispiel für die gleiche Provinz. Wenn dies der Fall ist, können Sie die ursprünglichen Daten in einem Rutsch reduzieren, um Ihr Ziel zu erreichen, indem Sie eine update Anweisung mit einer by Anweisung verwenden. In meinem Code erstellt der erste Verweis auf das Dataset mit obs=0 nur die Variablen, der zweite Verweis die Werte und die by-Anweisung stellt sicher, dass nur eine Zeile pro Providence aktualisiert wird.

Mit dieser Methode müssen die doppelten Werte nicht vorher identifiziert werden.

data have; 
input Province $ AGE BRTHYEAR Trans_id Morb_id VarX flag_duplicate; 
datalines; 
AB  36 1980  45654  .   .   0 
AB  36 1980   .  .  2135   1 
ON  26 1990   .  .  8868   0 
ON  26 1990   .  35464  8868   1 
; 
run; 

data want; 
update have(obs=0) have; 
by province; 
run; 
+0

Danke für die Antwort @Keith. Es gibt tatsächlich 35.000+ obs und die trans_id und morb_id sind die eindeutigen Identifikatoren für jeden Patienten (jeder obs wird nur einen der beiden haben, aber manchmal werden beide fehlen). Ich markierte Duplikate nach dem Sortieren von Daten (Sortierung nach 10 Variablen) basierend darauf, ob sie mit dem entsprechenden Verzögerungswert jeder sortierten Variablen übereinstimmten. – ASilva

+0

@ASilva Dann müssen Sie die 10 Variablen, nach denen Sie sortiert haben, in die 'by'-Anweisung des Datenschritts schreiben, den ich geschrieben habe. Dies sollte Ihnen das gewünschte Ergebnis geben. – Longfish

+0

Das scheint zu funktionieren! Danke vielmals. – ASilva

0

So etwas sollte funktionieren ...

proc sort data=uncleaned_data; by Province AGE BRTHYEAR; run; 

data cleaned_data (DROP=TRANS_ID RENAME=(KEEP_TRANS_ID=TRANS_ID) ...); 
set uncleaned_data; 
by Province AGE BRTHYEAR; 
if first.BRTHYEAR then do; 
keep_TRANS_ID=TRANS_ID; 
... 
end; 
else do; 
if keep_TRANS_ID=. then keep_TRANS_ID=TRANS_ID; 
... 
end; 
if last.BRTHYEAR then output; 
run; 
+0

Hallo! danke für die Antwort. Ich werde das versuchen, aber ich frage mich, ob es noch funktionieren wird, wenn ich 35.000+ Beobachtungen mit vielen Beobachtern habe, die das gleiche Geburtsjahr haben. Mein Duplikat-Flag-Code basierte auf 10 Variablenwerten, die mit den entsprechenden Verzögerungsvariablenwerten identisch waren (ich gab ein vereinfachtes Beispiel des Datensatzes). – ASilva

+0

Ja, das 'first.BRTHYEAR' ändert sich nur, wenn es die erste Beobachtung innerhalb der Untergruppe ist, die in diesem Fall jede einzelne ist. – dashnick

+0

Das schien nicht für mich zu funktionieren. Die Informationen werden nicht für fehlende Werte in den ursprünglichen oder doppelten Beobachtungen ausgefüllt. Vielen Dank für die Vorschläge. – ASilva

Verwandte Themen