Formate automatisieren

Aus SAS-Wiki
Wechseln zu: Navigation, Suche

Von Grischa Pfister: Hans-Peter Altenburg, Heinrich Stürzl, Almut Hahn, Carina Ortseifen, Grischa Pfister: Tipps und Tricks für den leichteren Umgang mit der SAS Software, KSFE 2008

Formate spielen in SAS/BASE eine herausragende Rolle. Sie werden für eine Vielzahl von Aufgaben verwendet, z. B. um kodierte Werte in der Anzeige durch Klartext zu ersetzen oder zur Klassifizierung von Gruppierungsvariablen. Typische Aufgaben aus dem Bereich Datenmanagement sind das Umschlüsseln von Werten und die Validierung von Daten. An dieser Stelle geht es um die Frage, wie Formate permanent gespeichert und dann vom SAS System auch wiedergefunden werden, und wie vorhandene Formate z. B. zu Dokumentationszwecken in SAS-Tabellen geschrieben werden können. Der umgekehrte Weg, nämlich Formate direkt aus SAS-Tabelle zu erzeugen, erlaubt die vollständige Automatisierung von Formaten und erleichtert die Aktualisierung wesentlich.

Formate permanent speichern

Formate werden permanent angelegt, indem beim Aufruf der Prozedur FORMAT noch der Name einer Bibliothek plus eventuell der Name eines Kataloges angegeben wird.

Proc Format lib=libref<.catalog>;

… Wird der Katalog weggelassen, speichert SAS die Formate automatisch in einem Katalog namens FORMATS. Ist ein Format permanent gespeichert, bedeutet das aber mitnichten, dass es auch automatisch in SAS zur Verfügung steht, denn es gibt hierfür vordefinierte Suchpfade und hier muss der eigene Katalog zunächst registriert werden. Die erste von zwei Möglichkeiten ist, den bereits vorhandenen Suchpfad zu nutzen. SAS sucht Formate zunächst in WORK.FORMATS, dann in LIBRARY.FORMATS um anschließend auf die vordefinierten Formate zuzugreifen. Die Bibliothek LIBRARY ist SAS-seitig nicht allokiert, sondern dient als Möglichkeit, eigene Formate ohne viel Aufwand verwenden zu können.

* GP Library fuer Formate anlegen **;
Libname gpFmt "d:/temp"; 

* GP Format in Katalog gpFmt.Formats erstellen *;
Proc Format lib=gpFmt;
  Value note
    1 = "toll"
    2 = "nicht so toll"
    other = "inakzeptabel"
  ;
Run;

* GP Test des Formates 
     -> wird nicht gefunden *;
Data _null_;
  x = 1;
  Put x= x=note.;
Run;

LOG:
12   Data _null_;
13     x = 1;
14     Put x= x=note.;
                -----
                48
ERROR 48-59: The format NOTE was not found or could not be loaded.

15   Run;
NOTE: The SAS System stopped processing this step because of errors. 

* GP Bibliothek LIBRARY setzen *;
Libname library (gpFmt); 

* GP Zweiter Test des Formates
     -> jetzt wird es gefunden *; 

Data _null_;
  x = 1;
  Put x= x=note.;
Run;

Im Beispiel wird zunächst eine Bibliothek allokiert und dann ein Format erstellt. Da kein Katalogname angegeben ist, wird automatisch FORMATS verwendet. Das ist auch gewollt, da später der automatische Suchpfad LIBRARY.FORMATS benutzt werden soll. Ein erster Test zeigt, dass das Format nicht zur Verfügung steht, deshalb wird anschließend in einem weiteren Libname-Statement die Bibliothek LIBRARY so angelegt, dass sie direkt auf die bereits vorhandene Bibliothek GPFMT verweist. Der anschließende Test zeigt, dass das Format jetzt gefunden wird.

Soll das Format in einer anderen Bibliothek und/oder in einem anderen Katalog gespeichert werden, oder gibt es mehrere Format-Kataloge, muss auf die Option FMTSEARCH zurückgegriffen werden. Sie steuert den Suchpfad für die benutzerspezifischen Formate. I.d.R. werden zunächst WORK.FORMATS und LIBRARY.FORMATS durchsucht, anschließend folgen die in FMTSEARCH angegebenen Kataloge, auch diese Reihenfolge ist aber beeinflussbar (vergl. [1] ab Seite 1648).

* GP Format neu anlegen in gpFmt.gpFormate *;
Proc Format lib=gpFmt.gpFormate;
  Value note
    1 = "toll"
    2 = "nicht so toll"
    other = "inakzeptabel"
  ;
Run;

* GP Suchpfad fuer Formate setzen *;
Options
  fmtsearch=(gpFmt.gpFormate)
;

* GP Format testen *;
Data _null_;
  x = 1;
  Put x= x=note.;
Run;

Das Format wird diesmal in einen eigenen Katalog gespeichert, der mit Hilfe von FMTSEARCH in den Suchpfad aufgenommen wird. Der anschließende Test zeigt, dass das Format gefunden wird. Dabei wird – abhängig von der Suchreihenfolge – das erste passende Format verwendet. Diese Konkatenierung von Katalogen kann übrigens auch anders erfolgen, seit Version 8 gibt es das CATNAME-Statement, das ebenfalls eine solche Funktionalität zur Verfügung stellt.

Proc Format lib=gpfmt.cat01;
  value test other = "cat01 test";
Run; 

Proc Format lib=gpfmt.cat02;
  value test other = "cat02 test";
  value cat other = "cat02";
Run;
Catname gpfmt.formats (gpfmt.cat01 gpfmt.cat02);

Options
  fmtsearch=(gpfmt)
;

Data _Null_;
  x = 1;
  put x = test.;
  Put x = cat.;
Run;
LOG:
x=cat01 test
x=cat02
NOTE: DATA statement used (Total process time):

Zunächst wird in Katalog GPFMT.CAT01 das Format TEST angelegt, in Katalog GPFMT.CAT02 sind es ebenfalls das Format TEST sowie ein Format CAT. Anschließend werden beide Kataloge zusammengefasst zum Katalog GPFMT.FORMATS, der dann via FMTSEARCH in den Suchpfad aufgenommen wird. Die Ausgabe im LOG zeigt, dass das Format TEST aus Katalog CAT01 verwendet wird, während Format CAT aus Katalog CAT02 genommen wird. Die Such-Reihenfolge wird in diesem Falle also durch die Angabe im CATNAME-Statement festgelegt, da in CAT01 bereits ein Format namens TEST gefunden wird, bleibt das gleichnamige Format in CAT02 unbeachtet.

Formate in eine SAS-Tabelle speichern

Dies ist zum einen hilfreich, wenn Formate von Dritten übernommen werden und der eigentliche Code nicht zur Verfügung steht. Aus der resultierenden Tabelle kann genau abgelesen werden, welche Klassifizierungen vorgenommen werden. Zum anderen kann dies auch ein sinnvolles Werkzeug für die Dokumentation von Formaten sein, da die reguläre Ausgabe von PROC FORMAT nicht als ODS-Outputobjekt angeboten wird.

* GP Format-Definition in Tabelle ausgeben *;
Options
  ls = 256
  nocenter
;
Proc Format lib=gpFmt.gpFormate cntlout = Work.Fmt_Note;
  Select note;
Run;

Proc Print Data = Work.Fmt_Note;
Run;

Durch Angabe der Option CNTLOUT=Libref.Table wird das Format in eine sog. Kontroll-Tabelle ausgegeben, die dann weiterverarbeitet werden kann. Eine genaue Beschreibung der Tabelle und der enthaltenen Tabelle bietet [2] ab Seite 466. 2.3 Formate aus Tabellen erstellen Diese Kontroll-Tabellen können natürlich auch verwendet werden, um ein Format neu zu erstellen, wobei der eigentlich interessante Ansatz ist, bereits vorhandene Tabellen so zu erweitern, dass sie als Input-Kontroll-Tabelle verwendet werden können. Dieser Ansatz wird in einer Vielzahl von Projekten verwendet, um automatisiert Anpassungen an Formaten vorzunehmen, die einer starken Dynamik unterliegen.

* GP Input Control Data Set fuer Format erzeugen *;
Proc Sql;
  Create View Work.Tmp As
    Select "name2sex" As fmtName, "C" As type,
      name As start, name As end, sex As label
    From Sashelp.Class
  ;
Quit;

Proc Format cntlin = Work.Tmp;
Run;
Data _Null_;
  Set Sashelp.Class(keep = name);
  Put name = @20 name $name2sex.;
Run;

Im Beispiel wird die Tabelle SASHELP.CLASS so umgewandelt, dass sich eine Input-Kontroll-Tabelle für PROC FORMAT ergibt. Die Konstante „name2sex“ wird als Format-Name (FMTNAME) angelegt, Beginn (START) und Ende (END) des jeweiligen Format-Bereiches werden durch die Variable NAME festgelegt. Der Format-Wert (LABEL) wird aus der Variable SEX ausgelesen. Ergebnis ist ein Format, das den Namen in das zugehörige Geschlecht übersetzt.

Literatur

  • SAS 9.1.3 - Language Reference: Dictionary, fifth Edition.
  • Base SAS 9.1.3 Procedures Guide, second Edition.