Die Schlüsselworte ALL, CHARACTER und NUMERIC

Aus SAS-Wiki
Wechseln zu: Navigation, Suche

Von Wilfried Schollenberger aus: Hans-Peter Altenburg, Carina Ortseifen, Tanja Petrowitsch, Grischa Pfister, Wilfried Schollenberger: Tipps & Tricks für den leichteren Umgang mit der SAS Software, KSFE 2007

Dieser Tipp beschreibt keine neue Funktion in SAS, sondern ist mehr eine Erinnerung. Die Verwendung in der Array-Anweisung ist bereits für die Version 6.06 im Language Guide dokumentiert.

Beschreibung der Schlüsselworte

Die Schlüsselworte werden in den folgenden Beispielen in den Anweisungen Array, Format und By verwendet. Dabei haben die Schlüsselworte folgende Bedeutung:

  • _All_ steht für die Liste aller Variablen
  • _Character_ steht für die Liste aller alphanumerischen Variablen
  • _Numeric_ steht für die Liste aller numerischen Variablen

Normalerweise sollten in produktiven Programmen möglichst alle Variablen explizit aufgeführt werden. Es gibt aber Fälle, insbesondere bei allgemein verwendbaren Makros und bei Ad-hoc-Auswertungen, in denen diese impliziten Listen sehr nützlich sind.

Beispiel: Alle alphanumerischen Variablen in Großbuchstaben umwandeln

Im ersten Beispiel werden alle alphanumerischen Variablen in Großbuchstaben umgewandelt:

Data work.gross;
	 Set work.gemischt;
	 Array _ac _CHARACTER_;
	 do over _ac;
		 _ac = upcase(_ac);
	 end;
Run;

Wenn einzelne Variablen nicht umgewandelt werden sollen, kann man den Variablen-Namen mit der Funktion Vname() abfragen, wie in

Beispiel:

Data work.gross;
 	Set gemischt;
 	Array _ac _CHARACTER_;
 	do over _ac;
 		if lowcase(vname(_ac)) NOT IN ("name", "vorname") 
 			then _ac = upcase(_ac);
 	end;
Run;


Beispiel: Alle numerischen Variablen runden

Auf der letzten KSFE wurde gezeigt, dass es bei Dezimalzahlen zu Rundungs-Problemen kommen kann, weil SAS intern mit einer Gleitkomma-Darstellung rechnet. Deshalb ist es manchmal sinnvoll, alle numerischen Variablen auf eine definierte Anzahl von Nachkommastellen zu runden:

	Data work.gerundet;
		Set original;
		Array _an _NUMERIC_;
		do over _an;
			_an = round(_an,0.01);
		end;
	Run;

Natürlich können auch hier, wie oben beschrieben, einzelne Variablen vom Runden ausgenommen werden.

Beispiel: Einheitliche Formatierung von Variablen

Es kommt immer wieder vor, dass in SAS-Dateien die Format-Angaben fehlen. Bei Datenbank-Tabellen gibt es auch gar keine Möglichkeit, SAS-Formate fest zuzuordnen. Hier können dann einheitliche Formate beim Prozedur-Aufruf vergeben werden:

	Proc fsview data=ksfe.bsp1;
		Format _NUMERIC_ commax12.2;
	Run;

Danach kann diese „Voreinstellung“ für einzelne Variablen wieder überschrieben werden:

	Proc fsview data=ksfe.bsp1;
		Format _NUMERIC_ commax12.2
			datum deudfdd10.;
	Run;

Beispiel: Erstellen einer CSV-Datei

Auch beim „manuellen“ Erstellen einer CSV-Datei sind diese Schlüsselworte hilfreich. In diesem Beispiel werden zunächst alle alphanumerischen und dann alle numerischen Variablen ausgegeben.

	Data _null_;
		Set ksfe.bsp1;
		Format _CHARACTER_ $quote200.
	     	  _NUMERIC_ numx16.8
		       datum deudfdd10.;
		Array _an _NUMERIC_;
		Array _ac _CHARACTER_;
		File "Test.csv" dlm=";";
		/* Spalten-Überschriften mit den Variablen-Namen */
		if _N_ EQ 1 then do;
	     	do over _ac;
	         		_vn = vname(_ac);
	         		Put _vn : $quote40. @;
	     	end;
     		do over _an;
          		_vn = vname(_an);
          		Put _vn : $quote40. @;
      		end;
      		Put;
  	 	end;

		/* Werte */
		do over _ac;
    			Put _ac @;
 		end;
 		do over _an;
    			Put _an @;
 		end;
 		Put;
	Run;

Auch hier wird das allgemeine Format Numx.32.16 für den Datumswert wieder überschrieben. Statt der Variablen-Namen könnte man natürlich auch Variablen-Labels (mit Vlabel()) verwenden.

Beispiel: Vergleich zweier Dateien

Im letzten Beispiel zu diesem Tipp geht es um den Vergleich zweier Dateien. Dafür gibt es die Prozedur Compare, welche die einzelnen Werte vergleicht. Wenn es aber nur wichtig ist, ob sich einzelne Zeilen einer SAS-Tabelle unterscheiden, und dann ein Programm verschiedene Aktionen ausführen soll, ist ein Daten-Schritt möglicherweise viel praktischer. Zunächst werden Schlüssel-Variablen benötigt, die jede Zeile eindeutig identifizieren. Im Beispiel sind das die Variablen kunde, datum und produkt. Dann müssen beide Dateien nach diesen Variablen sortiert werden. In der By-Untergruppen-Verarbeitung wird dann hinter diesen Schlüssel-Variablen mit _All_ bewirkt, dass alle anderen Variablen verglichen werden. Mit dem folgenden Daten-Schritt können dann alle Fälle unterschieden und verarbeitet werden:

 	Data work.vergleich;
       Merge ksfe.bsp1 (in = _d1)
          	 ksfe.bsp2 (in = _d2) ;
  		By kunde datum produkt _ALL_;
  		Length Vergleich $11;

		* gleiche Daten (interessieren heute nicht);
  		if _d1 AND _d2 then Delete;  

		* neue und gelöschte Zeilen;
  		else if first.produkt AND last.Produkt then do;
      		if _d1 then vergleich = "gelöscht";
               else vergleich = "neuer Satz";
  		end;

		* geänderte Werte;
		else do;
      		if _d1 then vergleich = "alter Wert";
          	       else vergleich = "neuer Wert";
  		end;	 
	Run;

Die Ergebnisdatei könnte dann z.B. so aussehen:

Tabelle.JPG

Erzeugt mit:

	ODS rtf file="~/k.rtf";
	Proc print  data=vergleich;
 		BY kunde datum produkt ;
 		ID kunde datum produkt Vergleich;
 		Format _numeric_ commax6.2 datum deudfdd10.;
	Run;
	ODS rtf close;

Literatur

  • SAS Language Guide, alle Versionen ab 6.06, Beschreibung von Array
  • Die Verwendung in den Format- und Informat-Anweisungen ist leider undokumentiert.