LesezeichenAbonnierenRSS-Feed abonnieren
sauer
Obsidian | Level 7

Hallo zusammen,

 

vielleicht hat jemad einen Hinweis für mich, wie man mein Problem am elegantesten lösen kann.

Ich habe allerdings noch keinen vernünftigen Ansatzpunkt 😞

Beispieldatensatz:

nr test1 test2

1 0 1

1 1 1

1 0 0

3 1 0

3 1 0

3 0 1

4 0 0

4 0 1

4 1 1

 

Aus diesem Datensatz will ich die mit gleicher nr "herausnehmen" und an ein makro übergeben, was mir Sensitivität, PPV usw. berechnet. Solange, bis alle nr abgearbeitet sind.

Danke schon mal.

Viele Grüße

Frank

 

 

 

6 ANTWORTEN 6
Kurt_Bremser
Super User

Mit proc sort nodupkey eine Liste der Nummern erzeugen, und dann mit der einen data _null_ step "füttern" und mit call execute den Makro aufrufen.

FreelanceReinh
Jade | Level 19

Wenn das Makro unveränderbar vorliegt, ist der von Kurt Bremser skizzierte Ansatz sicher eine gute Lösungsmöglichkeit. Sollte das Makro dagegen Teil des zu entwickelnden Codes sein, würde ich es gleich so programmieren, dass es die Verarbeitung von BY-Gruppen beherrscht. Denn die gewünschten Berechnungen für den Beispieldatensatz würde man doch wahrscheinlich entweder in einem Datastep (mit set ...; by nr;) oder mit Hilfe von PROC FREQ (ebenfalls by nr;) durchführen. (Für letzteres, jedoch ohne BY-Gruppen, siehe http://support.sas.com/kb/24/170.html.)

mfab
Quartz | Level 8

Hallo Frank,

 

ich würde auch schauen, dass die Verarbeitung mit einem BY-Statement alle Datensätze abarbeiten kann.

 

 

Alternativ kann z.B. mit einem Hash immer ein entsprechendes Dataset erzeugt werden und mit Call-Execute in einem Macro verarbeitet werden.

Dabei könnten sogar die Ergebnisse anschließend im gleichen Data Step wieder eingelesen und an die Original-Daten angefügt werden.

(Hier findet sich unter "Splitting A SAS File Dynamically Using The .OUTPUT() Method" ein Ansatz dafür)

 

Ein anderer Ansatz wäre die Ausgangsdaten (mit einem Hash) dynamisch in einzelne Datasets zu zerlegen und in einem Macro alle erzeugten Datasets zu verarbeiten.

 

Das hängt natürlich davon ab, wie mit den Ergebnissen weiter verfahren werden soll. Werden einzelne Datasets gebraucht oder wieder ein großes Dataset, etc...

 

Herzliche Grüße

Michael

jh_ti_bw
Obsidian | Level 7

Hallo Frank,

 

mit einem Macro geht das folgendermaßen:

 

data _test;
input nr test1 test2;
cards;
1 0 1
1 1 1
1 0 0
3 1 0
3 1 0
3 0 1
4 0 0
4 0 1
4 1 1
run;
%macro loop_freq(data);
  %local i n values;
  
/* ermitteln der Nummern */ Proc sql noprint; select distinct nr into :values separated by " " from &data.; %let n = &sqlobs.; quit;
Title "Loop über Nr"; %do i = 1 %to &n.; /* Hier findet jetzt die Verarbeitung statt im Beispiel Freq*/ footnote "Verarbeitung von Nr: %scan(&values.,&i.,%str( ))"; Proc freq data = &data.; table test1*test2; where nr = %scan(&values.,&i.,%str( )); run; footnote; %end; title; %mend; ods html; %loop_freq(_test); ods html close;

Das funktioniert, solange alle Nummern in eine Macrovariable passen.

Anssonsten gibt es noch das bereits erwähnte Call execute und noch die Routine dosubl, die mithilfe des by-Statements aus dem Datastep aufgerufen werden können.

 

Viele Grüße

Jan

GrischaPfister
Fluorite | Level 6

Hallo Frank,

 

eine einfache Möglichkeit ist, die Makroaufrufe erzeugen zu lassen und dabe den Wert für NR zu übergeben, so dass das Makro dann entsprechend filtern kann. hier ein einfaches Beispiel:

Data Work.Test;
Input nr test1 test2;
cards;
1 0 1
1 1 1
1 0 0
3 1 0
3 1 0
3 0 1
4 0 0
4 0 1
4 1 1
;
run;

%Macro calc(n);
  %Put NOTE: [calc] do anything with &n..;
%Mend;

%Global code;
Proc Sql noprint;
  Select Distinct cats('%calc(',nr,')') Into :code Separated By " "
    From Work.Test
  ;
Quit;

%Put NOTE: code=%superq(code);

&code

Das Makro %CALC erzeugt in diesem Falle lediglich eine Ausgabe in das LOG mit dem Wert von NR, das entscheidende ist der PROC SQL Step. Hier wird der Makroaufruf zusammengesetzt und in eine Makro-Variable gespeichert.. Der Inhalt wird mit %Put in das LOG ausgegeben, anschließend wird mit &CODE der String mit den Makroaufrufen an den Input-Stack übergeben.

 

Hoffe, das hilft weiter, viele Grüße,

 

Grischa

sauer
Obsidian | Level 7

Vielen Dank für Eure Hilfe!

In den letzten Tagen habe ich mich dem Beispiel von Grischa beschäftigt und wieder mal einiges dazu gelernt 🙂

Auf jeden Fall bin ich zum Ziel gekommen.

Die anderen Beispiele werde ich mir auch noch vornehmen, im Moment hapert's nur mit der Zeit.

 

Danke nochmal und herzliche Grüße

Frank

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

Diskussionsstatistiken
  • 6 Antworten
  • 3332 Aufrufe
  • 1 Kudo
  • 6 in Unterhaltung