Community deutschsprachiger SAS-Anwender und -Programmierer

Antworten
Dies ist eine offene Gruppe. Melden Sie sich an und klicken Sie auf die Schaltfläche „Gruppe beitreten“, um Mitglied zu werden und damit zu beginnen, Beiträge in dieser Gruppe zu veröffentlichen.
Highlighted
Contributor
Beiträge: 50
Datensatz filtern

Hallo zusammen,

 

ich habe folgende Tabelle aus der ich einen bestimmten Datensatz herausfiltern muss:

 

SAS.png

 

In der 2. Spalte springt ein Fall ggf. von A nach B oder C, N ... Die Daten sind nach Kundennummer und Datum aufsteigend sortiert. Bei dem angegebenen Kunden bräuchte ich in diesem Fall aus Spalte 2 die aktuelle Bewertung (=B) und aus der Datumsspalte, wann der Kunde zum letzten Mal in diese Bewertung gefallen ist (=9.Sep. 2015)

 

Langsam verzweifle ich, vielleicht kann jemand helfen (im DI Studio oder Enterprise Guide)?

Vielen Dank!

Super User
Beiträge: 9.290
Betreff: Datensatz filtern

Bitte, bitte, Daten nicht als Bilder posten.

Wenn ich da was testen will, muss ich alles aus dem Bild abtippen.

Bitte lieber gleich einen Data Step mit datalines in ein Code-Window posten.

 

Dieses gesagt:

data want;
set have;
by customer;
retain change_date;
lastbew = lag(bewertung);
if first.customer
then change_date = .;
else
  if bewertung = 'B' and lastbew ne 'B'
  then change_date = date;
format change_date datetime19.;
if last.customer then output;
run;
---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
How to convert datasets to data steps
How to post code
Contributor
Beiträge: 50
Betreff: Datensatz filtern
Posted in reply to KurtBremser
Vielen Dank und Entschuldigung !
Occasional Contributor
Beiträge: 12
Betreff: Datensatz filtern

Hallo Fay123,

 

Testdaten in kopierbarer Form wären nett Smiley (zwinkernd)

 

Anbei meine Lösung mit dem beliebten "IF first. und last." und "Retain".

 

data EINGABE;
input KUNDENNUMMER BEWERTUNG $ DATUM;
attrib DATUM format=DDMMYYP10.;
cards;
1 A 19999
1 B 20000
1 A 20001
1 A 20002
1 B 20003
1 B 20004
2 A 19999
2 B 20000
2 A 20001
2 A 20002
2 B 20003
2 A 20004
;;;;
run;

proc sort data=EINGABE;
  by KUNDENNUMMER DATUM;
run;

data ERGEBNIS (drop=DATUM_R BEWERTUNG_R);
  set EINGABE;
  by KUNDENNUMMER;
  retain BEWERTUNG_R;
  retain DATUM_R;
  if first.KUNDENNUMMER then do;
    BEWERTUNG_R = Bewertung;
	DATUM_R = DATUM;
  end;

  if BEWERTUNG_R ne BEWERTUNG then do;
    BEWERTUNG_R = Bewertung;
    DATUM_R = DATUM;
  end;

  if last.KUNDENNUMMER then do;
    DATUM = DATUM_R;
	output;
  end;
run;
Contributor
Beiträge: 50
Betreff: Datensatz filtern
Posted in reply to CKothenschulte
Danke sehr! :-)
Contributor
Beiträge: 50
Betreff: Datensatz filtern
Posted in reply to CKothenschulte

Jetzt muss ich bei meinem Datensatz noch einmal nachfragen. Herauskommen sollen Bewertung und Datum der letzten Änderung, aktuell also bei mir: Bewertung B und Datum 9.9.2015. Heraus kommt bei dem Programm allerdings A und der 30.05.2012.

 

Kundennummer Bewertung Datum

1022-01 A 300512
1022-01 B 130612

1022-01 A 200815
1022-01 A 030915
1022-01 B 090915
1022-01 B 031215
1022-01 B 160316
1022-01 B 170616
1022-01 B 090916
1022-01 B 081216
1022-01 B 090317
1022-01 B 210617
1022-01 B 150917
1022-01 B 121217

 

Merci

Occasional Contributor
Beiträge: 12
Betreff: Datensatz filtern

Passt eventuell was mit der Datenstrukur nicht?

Ich habe mein Testdatenprogramm (nur den ersten Data-Step!) angepasst, damit die Kundenummer alphanumerisch ist und das Datum richtig interpretiert wird.

 

data EINGABE (drop=DATUMC);
input KUNDENNUMMER $ BEWERTUNG $ DATUMC $;
datum = mdy(input(substr(DATUMC,3,2),2.), input(substr(DATUMC,1,2),2.), 2000 + input(substr(DATUMC,5,2),2.));
attrib DATUM format=DDMMYYP10.;
cards;
1022-01 A 300512
1022-01 B 130612
1022-01 A 200815
1022-01 A 030915
1022-01 B 090915
1022-01 B 031215
1022-01 B 160316
1022-01 B 170616
1022-01 B 090916
1022-01 B 081216
1022-01 B 090317
1022-01 B 210617
1022-01 B 150917
1022-01 B 121217
;;;;
run;

proc sort data=EINGABE;
  by KUNDENNUMMER DATUM;
run;

data ERGEBNIS (drop=DATUM_R BEWERTUNG_R);
  set EINGABE;
  by KUNDENNUMMER;
  retain BEWERTUNG_R;
  retain DATUM_R;
  if first.KUNDENNUMMER then do;
    BEWERTUNG_R = Bewertung;
	DATUM_R = DATUM;
  end;

  if BEWERTUNG_R ne BEWERTUNG then do;
    BEWERTUNG_R = Bewertung;
    DATUM_R = DATUM;
  end;

  if last.KUNDENNUMMER then do;
    DATUM = DATUM_R;
	output;
  end;
run;

Anschließend bekomme ich das korrekt Ergebnis:

KUNDENNUMMER BEWERTUNG datum
1022-01 B 09.09.2015

Super Contributor
Beiträge: 498
Betreff: Datensatz filtern

Eigentlich muss der Vorschlag von @KurtBremser nur etwas angepasst werden - ich verzichte auf die lag-Funktion. Muss noch mit mehreren Kundennummern getestet werden.

 

data work.Eingabe;
   attrib
      Kundennummer length= $ 7
      Bewertung length= $ 1
      Datum length= 8 format=ddmmyyp10. informat=ddmmyy.
   ;

   input Kundennummer Bewertung Datum;

   datalines;
1022-01 A 300512
1022-01 B 130612
1022-01 A 200815
1022-01 A 030915
1022-01 B 090915
1022-01 B 031215
1022-01 B 160316
1022-01 B 170616
1022-01 B 090916
1022-01 B 081216
1022-01 B 090317
1022-01 B 210617
1022-01 B 150917
1022-01 B 121217
;
run;


data work.Ziel;
   set work.Eingabe;
   by Kundennummer;

   length LetzteBewertung $ 1 LetzteAenderung 8;
   retain Letzte:;
   format LetzteAenderung ddmmyyp10.;

   if first.Kundennummer then do;
      call missing(of Letzte:);
   end;

   if Bewertung ^= LetzteBewertung then do;
      LetzteBewertung = Bewertung;
      LetzteAenderung = Datum;
   end;

   if last.Kundennummer then output;

   keep Kundennummer Letzte:;
run;
Occasional Contributor
Beiträge: 14
Betreff: Datensatz filtern

hallo,

 

mit lag():

 


data daten;
        input Kundennummer $ Bewertung $ Datumt $;
        cards;
1022-01 A 300512
1022-01 B 130612
1022-01 A 200815
1022-01 A 030915
1022-01 B 090915
1022-01 B 031215
1022-01 B 160316
1022-01 B 170616
1022-01 B 090916
1022-01 B 081216
1022-01 B 090317
1022-01 B 210617
1022-01 B 150917
1022-01 B 121217
;
run;
 
data ergebnis(keep=kundennummer bew dat);
retain bew dat;
        set daten;
        datum = input(datumt,ddmmyy6.);
        by kundennummer;
        if lag(bewertung) ne bewertung then do;
                bew = Bewertung;
                dat = datum;
        end;
        if first.kundennummer then do;
                bew = Bewertung;
                dat = datum;
        end;
        if last.kundennummer then output;
        format dat eurdfdd10.;
run;

viele Grüße. Heide

 

Contributor
Beiträge: 50
Betreff: Datensatz filtern
Posted in reply to HeideTribius

Vielen Dank an alle! Frau (fröhlich)

Contributor
Beiträge: 28
Betreff: Datensatz filtern
[ Bearbeitet ]

Hallo zusammen,

der letzte Lösungsvorschlag liefert nicht das Datum vom letzten Wechsel nach B sondern das Datum vom letzten Wechsel (egal wohin).

Mit geänderten Test-Daten sieht man den Fehler schnell:

Der Code

data daten;

input Kundennummer $ Bewertung $ Datumt $;

cards;

 

1022-01 A 300512

1022-01 B 130612

1022-01 A 200815

1022-01 A 030915

1022-01 B 090915

1022-01 B 031215

1022-01 B 160316

1022-01 B 170616

1022-01 B 090916

1022-01 B 081216

1022-01 A 090317

1022-01 A 210617

1022-01 A 150917

1022-01 A 121217

;

run;

data ergebnis(keep=kundennummer bew dat);

retain bew dat;

set daten;

datum = input(datumt,ddmmyy6.);

by kundennummer;

if lag(bewertung) ne bewertung then do;

 

bew = Bewertung;

dat = datum;

end;

if first.kundennummer then do;

 

bew = Bewertung;

dat = datum;

end;

if last.kundennummer then output;

format dat eurdfdd10.;

run;

 

liefert

Obs bew dat Kundennummer

1 A 09.03.2017 1022-01

 

Die Lösung von Kurt liefert auch mit diesen Daten das korrekte Datum

09.09.2015

Verwirrend ist, dass sie nicht die dazu passende Bewertung liefert, das war aber auch nicht gefordert.

 

Viele Grüße

Hans

 

Nachtrag: Alle Lösungen, außer die von Kurt, liefern mit den geänderten Test-Daten nicht das korrekte Datum 09.09.2015 sondern.

Occasional Contributor
Beiträge: 14
Betreff: Datensatz filtern
hallo Basefan,

lt. Aufgabenstellung sollte die "aktuelle Bewertung ... und aus der Datumsspalte, wann der Kunde zum letzten Mal in diese Bewertung gefallen ist " ermittelt werden.
Das klingt erst einmal nicht so, als sollte gezielt nach "Bewertung B" gesucht werden?
Andernfalls müsste in beiden Abfragen ("if lag(Bewertung)..." und "if first.kundennummer") die Zusatzbedinung "and Bewertung = "B"" untergebracht werden.

viele Grüße. Heide
Contributor
Beiträge: 28
Betreff: Datensatz filtern
Posted in reply to HeideTribius

Hallo Heide,

stimmt!

Ich hatte den Satz 'Bei dem angegebenen Kunden bräuchte ich in diesem Fall aus Spalte 2 die aktuelle Bewertung (=B) und aus der Datumsspalte, wann der Kunde zum letzten Mal in diese Bewertung gefallen ist (=9.Sep. 2015)' falsch verstanden. Ich hatte verstanden, dass es um den Wechsel nach B ginge.

Also sind Eure Lösungen korrekt und die von Kurt geht offensichtlich auch vom gleichen falschen Verständnis der Aufgabenstellung aus.

Sorry für die angerichtete Verwirrung.

 

Viele Grüße

Hans

Super User
Beiträge: 9.290
Betreff: Datensatz filtern

Wir sind in die selbe Grube gefallen.

 

Siehe Maxim 42 Smiley (zwinkernd)

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
How to convert datasets to data steps
How to post code
Contributor
Beiträge: 50
Betreff: Datensatz filtern
Posted in reply to KurtBremser

Nichtsdestotrotz habt ihr mir alle sehr geholfen. Danke nochmals dafür!