Vergleich mit missing value in Makros

Hallo, Community,

von einer (vorher sortierten) Liste numerischer Variablen, sagen wir x_1 ... x_10 mit "missings" soll der kleinste Wert gefunden werden und in eine neue Variable x_11 geschrieben werden.

Ich habe u. a. folgenden Code probiert:

/* zuerst Beispieldaten */
DATA a;
    
input x_1-x_10;
    
datalines;
    . . . .1 .3 .5 .6 .75 .8 1.0
    ;
RUN;

%MACRO missp;
DATA miss;
    SET a;
    
%LET I = 1;
    
%DO %WHILE (%Sysevalf(x_&i < 0));    * (1);
        
%LET i = %EVAL(&i+1);
    
%END;
    
%PUT &i x_&i;                * (2);
    
x_11 = x_&i;                * (3);
RUN;
%MEND miss_p;

%missp;

(1) SAS führt den Vergleich in der Bedingungsabfrage nicht wie gewollt durch. Im obigen Beispiel sollte die Schleife im 4. Durchlauf (I=4) abbrechen.
Die Kontrollausgabe (2) zeigt aber an:
1 x_1, d. h. die Bedingung ist bereits im ersten Durchlauf FALSE, wie auch das Logfile ausweist:
MLOGIC(MISS_P): %DO %WHILE(%Sysevalf(x_&i < 0)) loop beginning; condition is
FALSE. Loop will not be executed.

(Lt. Dokumentation ist ein "missing" kleiner als jeder numerische Wert.)

(3) Weiterhin funktioniert die Zuweisung des ersten "echten" Minimalwerts nicht korrekt, d. h. die Variable x_11 wird gar nicht angelegt (,bzw. wenn sie durch ein Statement x_11=0; vorher initiiert wurde, bekommt sie den Wert "missing").

Kann mir jemand meine Denkfehler überwinden helfen?
Danke und freundlichen Gruß

Meinhard Mende

Warum ein Makro?

Hallo,

in der Makro %Do %While Abfrage wird schlichtweg die Zeichenkette X_1 mit 0 verglichen. Und diese Bedingung ("X_1" lt 0) ist tatsächlich nicht erfüllt. Diese Zeichenkette hat aber nichts mit der Datastepvariablen X_1 zu tun.
Wenn man die Variablen X_1-X_10 in ein Array einliest, dann bekommt man das gewünschte Ergebnis durch einfachen Base-Code folgendermaßen:


DATA miss;
    
SET a;
    
array _x(10) x_1-x_10;
    i=
1;
    
do while (_x(i) <0);    * (1);
        
i = i+1;
    
end;
    
PUT i _x(i);                * (2);
    
x_11 = _x(i);                * (3);
RUN;

Grüße
Wolfgang Hornung

Warum den kompliziert ...

Vielen Dank, Wolfgang Hornung,

ja, ich habe mich zur Makro-Schleife verleiten lassen, weil die Variable X auch noch verschiedene Namen durchläuft.
In diesem Fall hat's aber die normale Schleife auch getan.

Nochmals Dank und Gruß

Meinhard Mende

Äpfel&Birnen-Vermischungs-Problem

Hallo,
wieder einmal scheint hier ein großes Äpfel & Birnen Problem vorzuliegen!
Wichtig ist zu beachten, dass mit %do eine Macro-Schleife eingeleitet wird, die zwar Base-Code erzeugt, das wird aber vor der SAS-Base-Laufzeit gemacht!
Erst nach dem SAS-Macro-Umsetzer ist das SAS-Base dran, und erst dabei wird dann ein SET zur Laufzeit abgearbeitet.

Faustregel: Macro-Sprache ist wie tippen von Code-Zeilen, nur eleganter.

Das heißt, dass die Macro-Schleife zwar durchlaufen wird (wie oft?), aber die Base-Variablen noch gar keinen Wert haben, weil der SET-Befehl (SET a;) noch gar nicht bearbeitet werden konnte, weil das SAS-Base noch nicht dran war!
Zum nachlesen zum Thema "SAS-Macro/SAS-Base":
Ansprechen einer Anzahl von Variablen über einen Schleifendurchlauf

Hilfe! Datumskonvertierung

Erklärungen zu den Fehlern

Gruß aus Betzdorf/Sieg

Hans Kneilmann, Schäfer Shop GmbH (SSI)

Noch einfacher ...

Hallo,

das Ganze läßt sich auch ohne eine Schleife lösen:

  x_11 = min(of x_1-x_10) ;

OK, aber welches ist das Minimum?

Vielen Dank, Herr Ritter,

Ihre Idee hatte ich auch schon verfolgt.
Weil ich aber den Index i brauche, für den x_i das Minimum erreicht, war sie hier nicht hilfreich.

Gruß
MM

Hallo Herr Mende,um an den

Hallo Herr Mende,

um an den Index zu kommen müssen Sie wohl über eine Schleife laufen.

Gruß
Lutz Ritter