Makro-Sprache und Datenschritt

Aus SAS-Wiki
Wechseln zu: Navigation, Suche

Zugriff auf Daten in SAS-Makros

Das SAS-System stellt zwei Funktionen bereit, die den Austausch zwischen SAS-Datenschritt und Makro-Sprache erlauben:

  • Symget: transferiert Inhalt einer Makro-Variable in den Datenschritt und
  • Symput: transferiert Datenschritt-Informationen in eine Makro-Variable.

Dieser Austausch ist notwendig, da die Variablen des SAS-Datenschritts und die Makro-Sprache in unterschiedlichen Speichern abgelegt werden. Die Datenschritt-Variablen werden in einen Speicher namens "Programm Data Vektor" geschrieben, die Makro-Sprache legt ihre Variablen in Symboltabellen ab ( siehe Lokale und globale Makrovariablen ). Um zwischen diesen Speichern Informationen auszutauschen, benötigen Sie die Funktionen Symput und Symget.

MacroProg PG4.gif

Der verwendete Speicher hängt ab:

  • von der Stelle, wo der Datenschritt aufgerufen wird,
  • von der Verschachtelung der Umgebungen und
  • von der Definition lokaler und globaler Variablen.

Symget-Funktion

Syntax:
Symget(Argument)

Datenschrittvariable = Symget(Argument);

Das Argument kann

  • eine in Anführungszeichen eingeschlossen Makrovariable,
  • eine Datenschritt-Zeichenkettenvariable oder
  • ein Datenschritt-Zeichenkettenausdruck

sein.

Die Datenschrittvariable

  • kann zuvor als Charakter- oder Numerische Variable definiert sein,
  • wird ansonsten als Charakter-Variable mit Länge 200 definiert,
  • wird - falls länger - auf 200 Zeichen gekürzt und
  • wird als Numerische-Variable definiert, falls die Symget-Funktion in einen arithmetischen Ausdruck eingesetzt wird.

Falls also mit mehr als 200 Zeichen in der Makrovariablen zu rechnen ist, muss die Datenschrittvariable entsprechend groß definiert werden.

Beispiel 1: Das Argument ist eine Zeichenkette
%Let name=recklinghausen;
Data loc;
  Input land $;
  stadt=Symget('name');
Cards;
Deutschland
;
Proc Print;
Run;
Ergebnis:
OBS LAND STADT
1 Deutschl recklinghausen

Der Makrovariablenname muss in Anführungszeichen eingeschlossen sein.

Beachtenswert ist, dass die durch die Symget-Funktion referenzierte Datenschrittvariable einen Wert mit mehr als 8 Buchstaben (bis zu 200 Buchstaben, recklinghausen=14 Buchstaben) annehmen kann, wobei bei der Variablen land die Eingabe standardmäßig auf 8 Zeichen begrenzt ist. Dies ist durch die unterschiedlichen Speicher bedingt und kann Probleme mit der Speicherkapazität verursachen, da jede Makrovariable standardmäßig mit 200 Zeichen abgelegt wird, auch wenn diese nur 14 Zeichen hat. Durch Vereinbaren eines Input-Formats kann dies begrenzt werden (siehe Beispiel 3).

Beispiel 2: Das Argument ist eine Datenschrittvariable
%Let fluss=arno; 1) 
%Let land=Italien;
%Let stadt=roma;
Data loc;
  Input gebiet $ Zahl;
  name=Symget(gebiet); 2) 
Cards;
stadt 12 3) 
land 34
fluss 83
gebirge 97 4) 
;
Proc Print;
Run;
Ergebnis:
OBS GEBIET ZAHL NAME
1 stadt 12 roma
2 land 34 Italien
3 fluss 83 arno
4 gebirge 97

Die Ausprägung der Variable muss ein gültiger SAS-Makrovariablenname sein.

1) Es werden 3 Makrovariablen gebildet.
2) Die 3 Makrovariablen werden als gebiet definiert.
3) Beim Einlesen dieser Beobachtung wird überprüft, ob eine Makrovariable mit dem Namen stadt existiert. Wenn dies der Fall ist, wird ihr Wert aus dem Makro-Speicher übernommen.
4) Da keine Makrovariable gebirge vereinbart wurde, bekommt die Variable name an dieser Stelle einen Nullwert. Außerdem erscheint folgende Mitteilung:

NOTE: Invalid argument to function SYMGET at line 69 column 8.
RULE:      ----+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8-
74         gebirge 97
gebiet=gebirge Zahl=97 name=  _ERROR_=1 _N_=4
Beispiel 3: Bildung von numerischen Variablen
%Let einheit=1.50;
Data dollars;
  Input dm;
  dollar1=dm*Input(Symget('einheit'),4.); 1) 
  dollar2=dm*Symgetn('einheit'); 2) 
Cards;
2.00
13.5
;
Proc print;
Run;
Ergebnis:
OBS DM DOLLAR1 DOLLAR2
1 2.0 3.00 3.00
2 13.5 20.25 20.25

1) Hier wird die Symget-Funktion dazu benutzt, einen numerischen Wert, der mit Hilfe der Makro-Sprache definiert wurde, in einem arithmetischen Ausdruck eines Datenschritts zu benutzen. Mit der Input-Funktion wird das Format 4. zugewiesen.
2) symgetn wird im Folgenden vorgestellt.

Symgetn-Funktion

Syntax:
Symgetn(Argument)

Datenschrittvariable = Symgetn(Argument);

Das Argument kann

  • eine in Anführungszeichen eingeschlossen Makrovariable,
  • eine Datenschritt-Zeichenkettenvariable oder
  • ein Datenschritt-Zeichenkettenausdruck

sein.

Die Datenschrittvariable

  • kann zuvor als Charakter- oder Numerische Variable definiert sein,
  • wird ansonsten als Numerische Variable definiert
Beispiel:
%Let txt = Ein Text;
%Let val = 5;
%Put VOR dem Data Step: text=&txt, val=&val;
Data _Null_;
  Length value 8 text $256;
  text  = symget("txt");
  value = symgetn("val");
  Put "IM Data Step: " text= value=;
Run;
Ergebnis:
VOR dem Data Step: text=Ein Text, val=5
IM Data Step: text=Ein Text value=5

Symput-Funktion

Die Symput-Funktion kann einen Wert aus einem SAS-Datenschritt an eine Makrovariable übergeben. Die Symput-Funktion kann dazu benutzt werden,

  • Informationen einer Prozedurausgabe in eine Makrovariable zu transferieren,
  • Möglichkeiten des Datenschritts (z.B. Input) zur Bildung von Makrovariablen zu verwenden,
  • SAS-Datensatz-Informationen, z.B. Label, Format, in Makros zu transportieren.
Syntax:
Call Symput(Argument1, Argument2);

Die Funktion weist den Wert von argument2 der Makrovariablen argument1 zu. Argument1 ist der Name der Makrovariablen. Argument2 gibt den Wert an, der der Makrovariablen zugewiesen werden soll. Die Argumente können

  • Zeichenketten sein,
  • Datenschritt-Zeichenkettenvariablen oder
  • Datenschritt-Zeichenkettenausdrücke

sein.

Beispiel 1: Beide Argumente sind Zeichenketten
Data;
  Call Symput ('stadt', 'London');
Run;
%Put Stadt=&stadt;
Ergebnis:
Stadt=London

Die Argumente müssen in Anführungszeichen eingeschlossen werden.

Beispiel 2: Beide Argumente sind Datenschrittvariablen
Data loc;
  Input gebiet $ name $;
  Call Symput(gebiet,name);
Cards;
stadt London
land England
fluss Themse
;
%Put Stadt=&stadt Land=&land Fluss=&fluss;
Ergebnis:
 Stadt=London Land=England Fluss=Themse

Die Argumente dürfen nicht in Anführungszeichen eingeschlossen sein und der Wert des 1. Arguments muss ein gültiger Makrovariablenname sein.
Es werden 3 Makrovariablen hergestellt (alle Ausprägungen der Variablen gebiet). Durch die Symput-Funktion bekommen sie die Werte London England Themse zugewiesen.

Beispiel 3: Argument2 ist das Ergebnis einer Datenschritt-Funktion
Data;
  Call Symput('datum', Put(Today(),ddmmyy8.));
Run;
%Put datum=&datum;
Ergebnis:
 datum=13/07/95

In diesem Beispiel wird das Argument2 durch eine Put-Funktion referenziert. Die Makrovariable datum ist das Ergebnis der Today-Funktion des Datenschritts (Die leere Klammer hinter der Today-Funktion teilt SAS mit, dass es sich um eine Datenschrittfunktion handelt, und nicht um eine Variable). Mit Hilfe der %Put-Anweisung wird dieser Wert ausgegeben.

Symputx-Funktion

Die Symputx-Funktion übergibt den Wert einer numerischen SAS-Datenschrittvariablen an eine Makrovariable.

Syntax:
Call Symputx(Argument1, Argument2);

Die Funktion weist den Wert von argument2 der Makrovariablen argument1 zu. Argument1 ist der Name der Makrovariablen. Argument2 gibt den Wert an, der der Makrovariablen zugewiesen werden soll.

Beispiel 1:
%Let txt = Ein Text;
%Let val = 5;
%Put VOR dem Data Step: text=&txt, val=&val;
Data test;
  text  = symget("txt");
  value = symgetn("val");
  Put "IM Data Step: " text= value=;
  Call Symput("text","Ein neuer Text");
  Call Symputx("val",1111);
Run;
%Put NACH dem Data Step: text=&text, val=&val;
Ergebnis:
VOR dem Data Step: text=Ein Text, val=5
IM Data Step: text=Ein Text value=5
NACH dem Data Step: text=Ein neuer Text, val=1111
Beispiel 2:
Data _Null_;
  x = 5;
  Call Symput("value",x); 1) 
  Call Symput("value",putn(x,"best.")); 2) 
  Call Symputx("value",x);
Run;

1) Erzeugt eine Note Meldung im Logfenster:

Numeric values have been converted to character values

2) Putn verhindert die Meldung im Logfenster.

Beispiel 3:
%Let maxAge = ;
%Let name =;
Data _null_;
  Set Sashelp.Class;
  If ( symgetn("maxAge") < age ) Then Do;
    Call Symputx("maxAge",age);
    Call Symput("name",name);
  End;
Run;
%Put Der/die älteste SchülerIn ist: &name mit &maxAge Jahren.;
Ergebnis:

Der/die älteste SchülerIn ist: Philip mit 16 Jahren.

Resolve-Funktion

Diese Funktion weist einer Datensatz-Variablen einen Wert zu. Die Länge, der mit Hilfe der Resolve-Funktion hergestellten Variablen, beträgt standardmäßig 200 Zeichen, was sich bei größeren Datenmengen auf die Rechengeschwindigkeit auswirken kann.

Syntax:
Resolve(Argument);

Argument ist ein Makro-Ausdruck:

  • Textstring in einfachen Anführungszeichen (Die Anführungszeichen hindern den Makro-Prozessor an der Auflösung des Makroausdrucks während des Datenschritts.)
    name=Resolve('%locate');
  • Name einer Datensatz-Variable (Der Inhalt der Datensatz-Variablen sollte ein Makro- Ausdruck sein.)
    adresse='%identi'
    Name=Resolve(adresse)
  • Zeichenkette, die einen Makro-Ausdruck erzeugt.
    region=Resolve('%land'||left(id))

Wenn Sie den Wert einer Variable mit Resolve bilden, hängt dieser von der Ausführung des Datenschritts ab. Wird der Wert als Makro-Variable gebildet, bleibt er während des Datenschritts konstant. Im Unterschied zu Symget erlaubt Resolve zusätzliche Argumentformen und ist flexibler einsetzbar, allerdings auch Ressourcen-intensiver.

Beispiel:
%Let event=lousisiana purchase;
%Macro date;
  1803
%Mend date;
%Let person1=Thomas Jefferson;
Data _null_;
  Length var1-var4 $20.; 1) 
  YEAR='%date';
  var1=Resolve('&event'); 2) 
  var2=Resolve('%date');
  var3=Resolve(year); 3) 
  var4=Resolve('&person'||left(_n_)); 4) 
  Put var1--var4; 5) 
Run;
Ergebnis:
 lousisiana purchase 1803 1803 Thomas Jefferson

1) Die Length-Anweisung definiert die Variablen var1-var4 mit einer Länge von 20 Zeichen. (Der Standard wäre 200 Zeichen.)
2) Die Variablen var1 und var2 werden zu Zeichenketten aufgelöst. var1 erhält den Wert louisiana purchase (Der Wert der Makrovariable event); var2 erhält durch die Auflösung des Makros date den Wert 1803.
3) var3 erhält den Wert der Datenschrittvariablen YEAR, der wiederum einen Makroaufruf beinhaltet, und löst sich somit ebenfalls zu 1803 auf.
4) var4 kombiniert die Zeichenkette &person und den Wert der automatischen Zählvariablen _N_, um die Makro-Variable &person1 zu referenzieren, und letztendlich zu Thomas Jefferson aufzulösen. (Die left-Funktion schneidet die Leerzeichen ab die links von _N_ auftauchen.)
5) Die Put-Anweisung schreibt das Ergebnis ins Log-Fenster.


Makros werden in der Resolve Anweisung nicht ausgeführt, sondern es wird lediglich der vom Makro erzeugte SAS Base Code zurückgegeben!

Beispiel:
%Macro p(table);
  Proc Sql;
    Select * From &table;
  Quit;
%Mend;
%Macro date;
  %Sysfunc(putn(%Sysfunc(date()),ddmmyyp10.))
%Mend;
Data _Null_;
  x = resolve('%p');
  Put x=;
  y = resolve('%date');
  Put y=;
Run;
Ergebnis:
x=Proc Sql;     Select * From ;   Quit;
y=08.12.2012

Execute-Routine

Die Execute-Routine kann innerhalb eines Datenschritts ein Makro aufrufen, das am Ende des Datenschritts ausgeführt wird.

Syntax:
Call Execute(Argument);

Das Argument kann

  • eine in einfache Anführungszeichen eingeschlossene Zeichenkette sein, (Die Anführungszeichen hindern den Makro-Prozessor am Auflösen des Makro-Ausdrucks während des Datenschritts.)
    Call Execute('%sales');
  • eine Datenschrittvariable sein, deren Wert ein Makro-Aufruf ist,
    findit='%finde';
    Call execute(findit);
  • eine Zeichenkette sein, die einen Makro-Ausdruck erzeugt.
    Call Execute('%sales('||month||')');
Beispiel:
%Macro mak1;
  Proc Print Data=neu;
    Where ware=1;
    Sum anzahl;
    Title "Anzahl aller bestellten Mixer";
  Run;
%Mend mak1;
%Macro mak2;
  Proc Print Data=neu;
    Where ware=2;
    Sum anzahl;
    Title "Anzahl aller bestellten Waagen";
  Run;
%Mend mak2;
Data Bestell;
  Input ware anzahl;
Datalines;
1 12
2 24
3 83
2 0
;
Run;
Data neu;
  Set bestell;
  If anzahl=0 Then Delete;
  If ware=1 Then Call Execute('%mak1'); 1) 
  Else If ware=2 Then Call Execute('%mak2');
Run;

1) In diesem Beispiel wird mit Hilfe der Execute-Routine das Makro mak1 aufgerufen, dass die Prozedur Print aufruft, und ausgibt, ob ware mit der Ausprägung 1 bestellt wurde. Für ware=2 wird das Makro mak2 aufgerufen.

Siehe auch

Literatur

  • Ortseifen, C.(1993): Einführung in die SAS-Makro-Programmierung - Begleitskript zur Vorlesung Wintersemester 1993/1994 - nicht veröffentlicht.
  • SAS 9.3 Macro Language – Reference.