Praxis Beispiel Annotate – ein Balkendiagramm erweitern

Aus SAS-Wiki
Wechseln zu: Navigation, Suche

Von Grischa Pfister aus: Carina Ortseifen, Grischa Pfister, Heribert Ramroth, Marianne Weires: Tipps und Tricks für den leichteren Umgang mit der SAS Software, KSFE 2010.

Ausgangspunkt ist ein Balkendiagramm, das einen statistischen Kennwert für verschiendene Pflanzen-Varietäten aufzeigt, die auf unterschiedlichen Bodentypen gezogen wurden.

Saswiki.JPG

Zusätzlich zu den angezeigten Mittelwerten sollen für jeden Balken noch die Extremwerte dargestellt werden.

Saswiki2.JPG

Das ist ein typisches Beispiel für den Einsatz der SAS/GRAPH Annotate Facility. Dieses Werkzeugt erlaubt die freie Grafikprogrammierung um entweder die Ausgabe der Standard-Prozeduren zu ergänzen, oder vollständig eigene Grafiken zu erstellen. Die Funktionsweise ist dabei, dass eine SAS-Tabelle pro Zeile jeweils eine Grafik-Steu¬eranweisung enthält, die einen gedachten Cursor innerhalb der Grafik bewegt und an gegebenen Koordinaten Grafikelemente erzeugt. Die Tabelle steuert, welche Aktion (was) an welcher Stelle (wo) gezeichnet wird, und wie das jeweilige graphische Element aussieht (wie). Dazu muss die Tabelle vordefiniert Variablen (Name, Typ und eventuell Länge) enthalten, die was, wo und wie genau beschreiben. Eine Annotate-Tabelle kann von Hand geschrieben werden, meistens wird sie jedoch aus den gleichen Daten gebildet, die auch für die eigentliche Grafik verwendet werden. Diese Ausgangstabelle wird eingelesen und mit Hilfe der typischen Data-Step Syntax – end=eof; If ( _N_ = 1); By-Verarbeitung; Output-Anweisung – werden dann die benötigten Sätze in die Annotate-Tabelle geschrieben.

In dem konkreten Fall soll mittig über jedem Balken eine vertikale Linie den Minimalwert mit dem Maximum verbinden. Außerdem soll an Minimum und Maximum für die bessere Lesbarkeit noch eine horizontale Linie (Whisker) ergänzt werden.

Saswiki3.JPG

Zunächst müssen die Koordinaten für die einzelnen Elemente ermittelt werden. Die Y-Werte sind schnell geklärt, denn die Ausgangstabelle enthält bereits die zwei Variablen LowerMu und UpperMu, die Minimum und Maximum für jeden Balken bereithalten.

Die X-Werte sind etwas spannender, denn erstens ist die X-Variable alphanumerisch und zweitens werden die Balken noch über eine GROUP-Option unterteilt. Für beides hält die Annotate Facility aber Lösungen bereit, denn für Diagramme mit alphanumerischen Koordinaten gibt es spezielle Variablen in der Annotate-Tabelle. Mit Hilfe einer GROUP-Variable wird die Gruppe angesteuert, XC enthält dann den alphanumerischen Wert, der den individuellen Balken innerhalb der Gruppe identifiziert.

Die vertikale Linie wird folgendermaßen gezeichnet: Mittels Annotate-Anweisungen (= Sätzen in der Annotate-Tabelle) wird der gedachte Cursor zunächst in einen Balken platziert (X-Koordinate) und zwar an die Y-Koordinate LowerMu. Dann wird eine Linie von LowerMu nach UpperMu gezeichnet.

Und die Whisker? Sie sollen als horizontale Linie an LowerMu/UpperMu erzeugt werden, die Frage ist aber, wie genau das passieren soll, denn es muss die X-Koordinate verändert werden. Die ist aber alphanumerisch – und da kann man schlecht um die Hälfte nach links oder rechts variieren. An dieser Stelle kommen die verschiedenen Bezugssysteme ins Spiel, die die Annotate Facility bietet. X- und Y-Koordinaten müssen sich auf ein konkretes System beziehen, damit SAS/GRAPH die Koordinatenangaben korrekt interpretieren kann. Grundsätzlich werden absolute Bezugssysteme (jede Koordinatenangabe bezieht sich auf den Ursprung) und relative Bezugssysteme (jede Koordinatenangabe bezieht sich auf die Angabe zuvor und enthält nur die Änderung in Bezug auf diese Koordinate) unterschieden. Dann gibt es verschiedene Räume, auf die sich die Koordinaten beziehen können, den Gesamtraum der Grafik, inklusive dem Platz für Titel und Fußnoten, den sog. Prozedurbereich, das ist der Platz, den die Grafik ohne Titel und Fußnoten einnimmt und als drittes der Datenbereich, das ist der Teil, der zum Beispiel durch die Achsen eines Balken- oder Liniendiagramms umfasst wird. In dem letztgenannten Bereich ist die Angabe von Koordinaten sehr einfach, da die Werte bereits in der Tabelle stecken, die für die Erstellung der ei¬gentlichen Grafik verwendet wird. Alternativ können Werte aber auch immer in Prozent angegeben werden, sodass die Fragestellung wie folgt beantwortet werden kann.

Die Whisker werden gezeichnet, indem zunächst der (gedachte) Cursor an die X-Koordinate Group/XC bewegt wird, d.h. der Cursor steht jetzt in der Mitte des Balkens – entweder an LowerMu oder UpperMu. Dann wird für die X-Koordinate das Bezugs¬system auf Prozent/relativ geändert und der Cursor um 1 % nach links bewegt. Anschließend wird die X-Koordinate um 2 % nach rechts bewegt und eine Linie gezeichnet.

Das vollständige Programm sieht dann so aus:

Data Work.Test_grafik;
Input  varietaet $ Bodenart_Karte $  Mu  LowerMu   UpperMu;
Cards;
   Cinerea      L               0.5611      0.4156      0.6967
   …
;
Run;

Pattern1 v=s c=blue; 
Pattern2 v=s c=red;
Pattern3 v=s c=green; 

* GP Aktivieren der Hilfs-Makros von Annotate *;
%Annomac;

%* GP Erzeugen der Annotate-Tabelle durch Einlesen 
     der Daten-Tabelle *;
Data Work.Anno;
  * GP Deklarieren der Annotate-Variablen ueber Hilfs-Makro *;
  %Dclanno;
  * GP Einstellen des Bezugs-Systems auf Daten fuer X und Y auf 
       Datenraum *; 
  %System(2,2);
  Set Work.Test_grafik;
  * GP Setzen von Standard-Werten *;
  * GP Annotate-Anweisungen werden nach der Prozedurausgabe 
       gezeichnet (after) *;
  when = "A";
  * GP Linientyp ist 1 (= durchgehende Linie) *;
  line = 1;
  * GP Linienstaerke ist 1 *;
  size = 1;
  * GP Linienfarbe ist Schwarz *;
  color = "black";

  * GP Angabe der X-Koordinaten mit Hilfe der Annotate-Variablen
       GROUP und XC *;
  group = varietaet;
  xc = bodenart_karte;

  * GP Unterer Whisker *;
  * GP Der Cursor wird auf die Y-Koordinate LowerMu gesetzt und die 
       erste Beobachtung in die Annotate-Tabelle geschrieben *;
  y = LowerMu;
  function="move";
  Output;

  * GP Das Bezugssystem fuer X-Koordinaten wird auf Prozent/relative 
       geaendert und der Cursor um ein Prozent nach links bewegt *;
  xsys = "7";
  x = -1;
  Output;
  * GP Jetzt wird von der vorherigen Koordinate ausgehend der Cursor
       um zwei Prozent nach rechts bewegt, dabei wird eine Linie
       gezeichnet *;
  x = +2;
  function="draw";
  Output;

  * GP Vertikale Linie LowerMu-UpperMu *;
  * GP Das Bezugssytem fuer X-Koordinaten wird wieder auf Datenraum
       umgestellt und der Cursor wieder an die Position GROUP/XC
       platziert *;
  xsys = "2";
  function="move";
  Output;
  * GP die Linie von LowerMu nach UpperMu wird gezeichnet *;
  y = UpperMu;
  function="draw";
  Output;

  * GP Oberer Whisker analog zu unterem Whisker *;
  function="move";
  Output;
  xsys = "7";
  x = -1;
  Output;
  x = +2;
  function="draw";
  Output;
Run;


* GP Erzeugen der Grafik inclusive Annotate *;
Proc Gchart data = Work.Test_grafik; 
  Vbar  bodenart_karte/ 
    sumvar    = mu 
    coutline  = black 
    group     = varietaet 
    patternid = group
    anno      = Work.Anno
  ; 
  Run;
Quit;

Und hier ist das dazugehörige Ergebnis:

Saswiki4.JPG