LesezeichenAbonnierenRSS-Feed abonnieren
sauer
Obsidian | Level 7

Hallo,

 

ich habe folgenden Datensatz mit nur einer Variable x:

1 1 1 0 1 1 0 0 0 1 0 1 1

Wenn die Variable x=0 wird, soll die aktuelle und die folgende Beobachtung gelöscht werden (oder gekennzeichnet werden).

Allerdings soll die Regel auch auf die Folgebeobachtung angewendet werden.

Das Ergebnis soll dann so aussehen (D=löschen):

1 1 1 D D 1 D D D D D D 1

 

Wie kann ich das erreichen?

 

Danke!

Viele Grüße

Frank

12 ANTWORTEN 12
AndreasMenrath
Pyrite | Level 9

Am einfachsten ist es sich zu merken, ob x=0 ist und dies dann in der Folgebeobachtung auszuwerten.

 

Hier ein Codebeispiel mit deinen Daten:

data test;
  length x 8;

  input x;
datalines;
1 
1 
1 
0 
1 
1 
0 
0 
0 
1 
0 
1 
1
;

run;


data cleaned;
   length deleteflag 8;
   retain deleteflag 0;

   set test;

   if (x eq 0) then do;
      deleteflag = 1;
   end;
   else do;
      /* Folgebeobachtung */
      if not deleteflag then do;
         output;
      end;
      deleteflag = 0;
   end;

   drop deleteflag;
run;

Gruß,

Andreas

sauer
Obsidian | Level 7

Funktioniert super!

Vielen Dank.

 

Grüße

Frank

sauer
Obsidian | Level 7

Hallo Andreas,

 

dummerweise habe ich eine Information vorenthalten und bin erst jetzt auf das Problem gestossen (weil mir immer Beobachtungen verschwanden..).

Es gibt noch eine Variable y , die die x gruppiert. Das Löschen der Folgebeaobachtung soll nur in der Gruppe stattfinden.

Also etwa so, die Gruppe 2 wird komplett gelöscht, aber 3 bleibt komplett erhalten.

Wie kann ich das erreichen?

 

data test;
  length x 8;

  input y x;
datalines;
1 1 
1 1 
1 1 
1 0 
1 1 
1 1 
2 0 
2 0 
2 0 
2 1 
2 0 
3 1 
3 1
;
run;

 

mfab
Quartz | Level 8

Hallo Frank,

 

dazu müsste dann die Gruppierungs-Variable noch geprüft werden.

 

Hier ein möglicher Ansatz:

Mit einem weiteren Retain könntest Du das y der vorherigen Zeile sichern und das dann in einer Bedingung zum Löschen, bzw. Setzen des "deleteflag" verwenden.

Alternativ gibt es auch die Möglichkeit mit einem "by y" zu arbeiten und dann die Prüfung, ob Du noch in der gleichen Gruppe bist mit lag(y) zu machen. Das gibt Dir dann das y der Vorzeile.

 

Wichtig ist in jedem Fall, dass die Daten vorher nach der Gruppierungs-Variable y sortiert sind.

 

Viele Grüße

Michael

AndreasMenrath
Pyrite | Level 9

Eine einfache BY Group Verarbeitung und die Prüfung per FIRST.Variablenname sollte das Problem lösen:

 


data cleaned;
   length deleteflag 8;
   retain deleteflag 0;

   set test;

   by y;

   if (first.y) then do;
/* delete flag für jede neue Gruppe zurücksetzen */ deleteflag = 0; end; if (x eq 0) then do; deleteflag = 1; end; else do; /* Folgebeobachtung */ if not deleteflag then do; output; end; deleteflag = 0; end; drop deleteflag; run;

Viele Grüße,

Andreas

sauer
Obsidian | Level 7

Hallo Andreas, hallo Michael,

 

gestern abend habe ich mit dem LAG Befehl experimentiert (den ich noch nie benutzt habe) ... und bin auf folgende Lösung gekommen. Ergebnis stimmt.

Habe ich richtig gedacht oder doch wieder irgendwo ein Ei gelegt?

 

Danke und viele Grüße

Frank

 

 

data test;
length x 8;
input zaehler y x;
datalines;
1 1 1
2 1 1
3 1 1
4 1 0
5 2 1
6 2 1
7 2 0
8 2 0
9 2 0
10 3 1
11 3 0
12 3 1
13 3 1
14 4 0
15 4 1
16 4 1
17 4 0
18 4 1
19 4 1
20 4 1
;
run;


data cleaned;
length deleteflag 8;
retain deleteflag 0;

set test;
ylag = lag(y);
if (x eq 0) then do;
deleteflag = 1;

end;
else do;
/* Folgebeobachtung */
if y ne ylag and deleteflag=1 then deleteflag=0;
if not deleteflag then output;
deleteflag = 0;
end;

drop deleteflag;
run;

Kurt_Bremser
Super User

Man muss bei der LAG()-Funktion immer im Auge behalten, dass sie ihren Speicher nur füllt, wenn sie aufgerufen wird. Daher ist es in der Regel falsch, sie innerhalb eines if oder einer do-Schleife zu verwenden.

mfab
Quartz | Level 8

Hallo zusammen,

 

Frank, das sieht doch gut aus - ich kann keine Fehler erkennen. (ylag würde ich noch droppen)

 

Persönlich würde ich mir jetzt das Length-Statement sparen. Das hat hier für mich einen deklarierenden Character, der meiner Ansicht nach nicht nötig ist, weil durch das Retain die Variable doch auch numerisch (Standard Länge 😎 aufgebaut wird.

 

Schöne Grüße

Michael

sauer
Obsidian | Level 7

Ja, stimmt .... über das drop hatte ich nachgedacht, war nicht sicher und habe es dann vergessen.

Also jetzt mit Schönheitskorrekturen:

 

data test;
input zaehler y x;
datalines;
1 1 1
2 1 1
3 1 1
4 1 0
5 2 1
6 2 1
7 2 0
8 2 0
9 2 0
10 3 1
11 3 0
12 3 1
13 3 1
14 4 0
15 4 1
16 4 1
17 4 0
18 4 1
19 4 1
20 4 1
;
run;

data cleaned;
retain deleteflag 0;
set test;
ylag=lag(y);

if (x eq 0) then
do;
deleteflag=1;
end;
else
do;

/* Folgebeobachtung */
if y ne ylag and deleteflag=1 then
deleteflag=0;

if not deleteflag then
output;
deleteflag=0;
end;
drop deleteflag;
drop ylag;
run;

FreelanceReinh
Jade | Level 19

Hallo, Frank,

 

wenn TEST nach Y sortiert ist und X keine Missings enthält, lässt sich die Selektion m. E. noch weiter vereinfachen:

 

data cleaned;
set test;
by y;
if x & (lag(x) | first.y);
run;

Ein Satz wird also genau dann ausgegeben, wenn

  1. X weder 0 noch missing ist und
  2. dies auch für das X des vorigen Satzes gilt, wobei diese Zusatzforderung für den jeweils ersten Satz einer Gruppe fallengelassen wird.

 

Viele Grüße

 

Reinhard

jakarman
Barite | Level 11

Wenn Sie die Funktion lag, kodieren sie bitte wie dassr queue Funktion.
Die lag von SQL bekannt, aber reagiert ganz anders. Deshalb ist es oft falsch.
Doch mit diesem Hintergrundwissen, dann kann man es hochgenaue und bequem nutzen.
http://rosettacode.org/wiki/Queue/Definition

---->-- ja karman --<-----
sauer
Obsidian | Level 7

Danke nochmal allen für die Vorschläge!

Es hat mich gut weitergebracht 😉

 

Frank

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

Diskussionsstatistiken
  • 12 Antworten
  • 2065 Aufrufe
  • 1 Kudo
  • 6 in Unterhaltung