SAS Programmierung für Fortgeschrittene I - SAS-Wiki
Transcription
SAS Programmierung für Fortgeschrittene I - SAS-Wiki
SAS Programmierung für Fortgeschrittene I Heinrich Stürzl ~creative · 'Cicommons Namensnennung ·Weitergabe unter gleichen Bedingungen 3.0 Unported (CC BY-SA 3.0) Dies 1st e1ne alltagssprachlide Zusammenfassung der Lizenz (die diese ndt ersetzt) Haftungsbeschränkung e Sie dürfen: Teilen- das Material in jedwedem Format oder Medium vervielfältigen und weiteiVerbreiten Bearbeiten- das Material remixen, verän-jern und darauf aufbauen und zwar fDr beliebige Zwecke, sogar kommerzielL Der Lizenzgeber kann diese Freiheiten nich: widerrufen solange Sie sich an die Lizenzbedingungen halten. Unter folgenden Bedingungen: Namensnennung- Sie müssen die Urheberschaft ausreichend deutlich benennen, einen Link zur Lizenz beifügen und angeben , ob Änderungen vorgenommen wurden . Diese Angaben dürfen in jeder angemessenen Art und W eise gemacht werden , allerdings nicht so, dass der Eindruck entsteht, der Lizenzgeber unterstütze gerade Sie oj er Ihre Nutzung des Werks besonders. @ Weitergabe unter gleichen Bedingungen- Wenn Sie das Material remixen, verändern oder anderweitig direkt darauf aJfbauen, dürfen Sie Ihre Beiträge nur unter derselben Lizenz wie das Original verbreiten. https://creativecommons.org/licenses/by-sa/3.0/deed.de ' SAS Programmierung für Fortgeschrittene I Inhalt Vorwort 1 Typographische Hinweise: 1 Literaturhinweise 2 DATA STEP Programmierung 4 1. Grundlagen des Datenschritts 5 1.1. Kompilierungsphase 5 1.2. Ausführungsphase 7 1.3. OUTPUT und DELETE 8 1.4 Automatische Datengenerierung 9 1.5 Data Step Debugger 11 1.6 RETAIN und SUM Anweisung 12 1.7 LAG und DIF Funktion 14 2. Tabellenoptionen (data set options) 16 3. Selektion von Beobachtungen (IF, WHERE, DELETE) 18 4. Einlesen von Daten aus externen Dateien 24 4.1. Einlesen von Daten im ASCII-Format (INFILE, INPUT) 24 4.2. Einlesen von Daten aus Microsoft Excel Tabellen 27 4.2.1 PROC IMPORT 27 4.2.2 LIBNAME Anweisung mit EXCEL Option 28 4.2.3 DDE 29 5. Verknüpfung von Tabellen (SET, MERGE) 5.1 SET 5.1.1 Optionen der SET Anweisung 5.2. MERGE 5.2.1 Optionen der MERGE Anweisung 5.3. By-Gruppen Verarbeitung (by-processing) mit SET und MERGE 6. Arrays SAS Programmierung für Fortgeschrittene I, Stürzl, Januar 08/SASFRT0.DOC 31 32 35 36 38 40 43 SAS Programmierung für Fortgeschrittene I 7. Vertikalisierung und Horizontalisierung von SAS Tabellen 46 7.1. Vertikalisierung 48 7.2. Horizontalisierung 50 8. Dictionary Tables 59 SAS Hilfe 1 1. SAS Help and Documentation Version 9 2 1.1. SAS OnlineDoc 9.1 for the Web 3 2. OnlineDoc Version 8 4 3. Online Hilfe Version 8 6 4. SAS Links 7 5. SAS Diskussionsforen 11 5.1. SAS-L 11 5.2. Redscope 13 5.3. User Forums von SAS Institute 14 5.4. SAS-EDU 14 5.5. Deutsches SAS-Forum 14 6. SAS Institute Listserver 15 7. Übung: SAS Hilfe 16 SAS Programmierung für Fortgeschrittene I, Stürzl, Januar 08/SASFRT0.DOC Vorwort Vorwort Das vorliegende Skript1 "SAS Programmierung für Fortgeschrittene I: Effiziente DATA-STEP Programmierung" ist als schriftliche Ergänzung zu dem gleichnamigen Kurs gedacht. Der Aufbau ist nicht unbedingt systematisch, sondern orientiert sich vielmehr am Kursablauf. Ziel dieses Kurses ist es, aufbauend auf dem Kurs "SAS für Anfänger" bzw. schon vorhandenen Grundkenntnissen in der Programmierung der Base SAS Software ein detailliertes Verständnis von der Funktionsweise des SAS DATA STEP, sowie die wesentlichen Techniken einer effizienten DATA-STEP Programmierung zu vermitteln, um damit Aufgaben von mittlerem bis hohem Schwierigkeitsgrad lösen zu können. Darüber hinaus wird ein Überblick gegeben, wo und wie man im Internet wertvolle Hinweise und Hilfe zu SAS finden kann und sich dort mit anderen SAS Programmierern austauschen kann. Nahezu alle hier dargestellten Inhalte der Base SAS Software gelten unabhängig von Windows für alle Betriebssysteme. Eine Ausnahme stellt das Kapitel "Einlesen von Daten aus Microsoft Excel Tabellen" dar. Der Kurs richtet sich deshalb nicht nur an Anwender von SAS unter Windows, sondern auch an SAS Programmierer anderer Betriebsysteme. Alle praktischen Übungen werden mit der aktuellen SAS Version unter Windows durchgeführt. Grundkenntnisse in Windows sind deshalb von Vorteil. Vorausgesetzt werden neben dem grundsätzlichen Umgang mit dem SAS System auf mindestens einem Betriebssystem vor allem die geläufige Handhabung und der vertraute Umgang mit Daten- und Prozedurschritten (DATA STEP, PROC STEP) sowie mit SAS Daten Bibliotheken (data libraries). Typographische Hinweise: Menüpunkte sind durch Fettdruck hervorgehoben, wobei Haupt- und Untermenüpunkte durch Î getrennt werden. Beispiel: Standard Short Cuts siehe Help Î SAS Help and Documentation Î Using SAS Software in Your Operating Environment Î Using SAS in Windows Î Running SAS under Windows Î Interacting with SAS under Windows Î Working within Your SAS Session Î Defining Keys SAS Programmcode erscheint in der Schriftart Courier fett gedruckt, wobei reservierte SAS-Schlüsselworte zur leichteren Unterscheidung groß und selbst definierte SAS-Bezeichnungen kursiv und klein dargestellt sind. Optionale Angaben stehen in spitzen Klammern. Ein funktionaler Unterschied zwischen Groß-/Kleinschreibung besteht nicht. (Ausnahme: Definition von Variablen im Data Step) Beispiel: DATA tabelle1 <tabelle2...>; 1 Das Werk ist einschließlich aller seiner Teile urheberrechtlich geschützt. Alle Rechte vorbehalten, einschließlich der Vervielfältigung - auch auszugsweise -, Übersetzung sowie Einspeicherung und Verarbeitung in elektronischen Systemen. SAS Programmierung für Fortgeschrittene I, Stürzl, Januar 08/SASFRT1.DOC Seite 1 von 59 Vorwort Literaturhinweise SAS Institute verlegt in der Reihe "Books by Users" (BBU) Bücher verschiedener Fremdautoren. Interessante Aufsätze zu verschiedenen SAS Themen sind in der Zeitschrift "Observation - The Technical Journal for SAS Software Users" bis Anfang 1997 in gedruckter Form erschienen und seitdem online verfügbar unter http://www.sas.com/service/doc/periodicals/obs/observations.html Für eine aktuelle Übersicht aller von SAS Institute verlegten Publikationen siehe "SAS Institute Publications Catalog" in gedruckter Form oder http://support.sas.com/publishing/ Die für diesen Kurs empfohlene Literatur ist in der nachfolgenden Liste nach Wichtigkeit absteigend geordnet. 1. SAS Language Reference: Concepts, Version 9.1, Vol 1-2, SAS Institute Inc. Allgemeine Beschreibung der Base SAS Software. Vermittelt ein detailliertes Verständnis der Grundlagen Online verfügbar, siehe Kapitel „SAS Hilfe“. 2. SAS Language Reference: Dictionary, Version 9.1, Vol 1-4, SAS Institute Inc. Referenz Handbuch der gesamten Base SAS Language, soweit sie unabhängig vom Betriebssystem ist. Online verfügbar, siehe Kapitel „SAS Hilfe“. 3. SAS 9.1Companion for Windows, Vol 1-2, SAS Institute Inc. Referenz Handbuch für SAS unter Windows mit ausführlichen Hinweisen zur Benutzeroberfläche und der windowsspezifischen Funktionalitäten der SAS Language Online verfügbar, siehe Kapitel „SAS Hilfe“. 4. Rick Aster, Professional SAS Programming Shortcuts, SAS Institute Inc. (BBU), Second Edition 2005. Umfangreiche, thematisch geordnete Sammlung von Base SAS Lösungen für eine Vielzahl von Aufgabenstellungen. 5. Phil Mason, In the Know ... SAS Tips and Techniques from Around the Globe, SAS Institute Inc. (BBU), 1996. Sammlung wertvoller Tipps aus dem Arbeitsalltag vieler SAS Anwender über Jahre gesammelt und übersichtlich zusammengestellt (Data Step, Procedures, Makro, SQL, SCL, FRAME Entries, ...). Die Perlen aus SAS-L. 6. SAS Programming Tips: A Guide to Efficient SAS Processing, SAS Institute Inc., 1990 Anhand von praxisnahen Beispielen werden verschiedene Lösungsmöglichkeiten desselben Problems in Bezug auf ihre Effizienz hinsichtlich Laufzeit und Speicherplatz verglichen. Basiert auf Version 6, aber trotzdem empfehlenswert. 7. A. Graf, C. Ortseifen, Statistische und grafische Datenanalyse mit SAS, Spektrum Akad. Verl., 1995, DM 68 Ziel ist es, für einen gegebenen Datenbestand und eine bestimmte Fragestellung die richtige Auswahl und Anwendung von SAS Prozeduren und der ihnen zugrundeliegenden statistischen Verfahren zu finden. Dies wird anhand zahlreicher Beispiele demonstriert, wobei die von den Prozeduren gelieferten Ergebnisse detailliert interpretiert werden. SAS Programmierung für Fortgeschrittene I, Stürzl, Januar 08/SASFRT1.DOC Seite 2 von 59 Vorwort Darüber hinaus sei auf folgende einführende Bücher verwiesen. 8. The Little SAS Book: A Primer, Third Edition, SAS Institute Inc. (BBU), € 48 Allgemeine Einführung in SAS Version 9 (inkl. SAS/STAT) für alle Betriebssysteme in englischer Sprache: "Getting started with SAS is easy with The Little SAS Book. This friendly, easy-to-read guide gently introduces you to the most commonly used features of SAS software plus a whole lot more! The book has been revised to include concepts of the Output Delivery System; the STYLE= option in the PRINT, REPORT, and TABULATE procedures; ODS HTML, RTF, PRINTER, and OUTPUT destinations; PROC REPORT; more on PROC TABULATE; exporting data; and the colon modifier for informats. You'll find clear and concise explanations of basic SAS concepts (such as DATA and PROC steps), inputting data, modifying and combining data sets, summarizing and presenting data, basic statistical procedures, and debugging SAS programs. Each topic is presented in a self-contained, two-page layout complete with examples and graphics. This format enables new users to get up and running quickly, while the examples allow you to type in the program and see it work!" SAS Programmierung für Fortgeschrittene I, Stürzl, Januar 08/SASFRT1.DOC Seite 3 von 59 DATA STEP Programmierung 1. Grundlagen des Datenschritts DATA STEP Programmierung Mit Hilfe des Datenschritts (DATA STEP) lässt sich eine oder mehrere SAS Tabellen (SAS data sets) erzeugen. Der Datenschritt beginnt mit dem Schlüsselwort DATA und den Namen der zu erstellenden SAS Tabellen. Jeder Datenschritt sollte mit der RUN Anweisung beendet werden. Syntax: DATA tabelle1 <tabelle2...>; Tabelle1, Tabelle2, .. steht für den vollständigen (zweiteiligen) Namen einer SAS Tabelle der Form libref.table-name. Dabei bezeichnet libref die Bibliothek, in der die Tabelle gespeichert wird und mit table-name wird der Name der Tabelle festgelegt. Falls nur table-name verwendet wird, so wird automatisch die Bibliothek "WORK" verwendet, d.h. die SAS Tabelle wird nur temporär bis zum Beenden des SAS Systems gespeichert (siehe Grundlagen, SAS Tabellen). Sonderfall: DATA _NULL_; erzeugt keine SAS Tabelle. Eine SAS Tabelle (data set) besteht aus den enthaltenen Daten und ihren Metainformationen. Die Daten können als rechteckige Matrix aus n Zeilen und m Spalten veranschaulicht werden. Jede Zeile bildet darin eine sogenannte Beobachtung (observation, row) bestehend aus den Ausprägungen (data values) von m verschiedenen Variablen (variables, columns). Die Metainformation (descriptor information) umfasst alle beschreibenden Informationen der Tabelle wie Dateiname, Größe, Erstellungsdatum, Anzahl der Beobachtungen und Variablen, Eigenschaften aller Variablen, etc. z.B. PROC CONTENTS Metainformation obs 1 2 var_1 var_2 ... var_m z.B. PROC PRINT ... ... n SAS Tabelle (data set) aus n Beobachtungen (observations) und m Variablen Im Datenschritt können Daten aus verschiedenen Quellen eingelesen und in nahezu beliebiger Weise verarbeitet werden. Dazu steht eine Vielfalt von Anweisungen und Funktionen zur Verfügung. Die Daten, die im Datenschritt verarbeitet werden, können sowohl aus externen (nicht-SAS) Dateien, als auch aus anderen SAS Tabellen stammen, oder aber im Programmtext eingebettet sein (DATALINES|CARDS) oder direkt generiert werden. Nicht-SAS Daten INFILE INPUT SET, MERGE UPDATE SAS Tabelle Data set Datenschritt DATA Step Externe (ASCII) Dateien und im Quelltext integrierte Daten werden mit Hilfe der INPUT Anweisung, andere SAS Tabellen mit den Anweisungen SET, MERGE oder UPDATE eingelesen. SAS Programmierung für Fortgeschrittene I, Stürzl, Januar 08/SASFRT1.DOC Seite 4 von 59 DATA STEP Programmierung 1. Grundlagen des Datenschritts 1. Grundlagen des Datenschritts Vor der Ausführung eines Datenschritts werden die Anweisungen des Programms während der Kompilierung auf ihre syntaktische Richtigkeit hin überprüft und alle benötigten Variablen temporär angelegt. Erst wenn der Datenschritt fehlerfrei kompiliert werden konnte, kommt er zur Ausführung, wobei die ausführbaren Anweisungen nacheinander auf jede Beobachtung angewendet werden (Implizite DO-Schleife). Kompilierungsphase 1. Syntaxprüfung 2. PDV erstellen Ausführungsphase Implizite DO-Schleife über alle Beobachtungen 1.1. Kompilierungsphase Während der Kompilierung wird der Datenschritt zunächst vom Word Scanner (tokenizer) auf korrekte Syntax überprüft und falls keine Fehler gefunden werden, automatisch kompiliert, d.h. in Maschinensprache übersetzt. Außerdem werden alle Deklarationsanweisungen (declarative statements) wie z.B. WHERE, LENGTH, RETAIN, ARRAY, BY, KEEP, DROP, RENAME, FORMAT, INFORMAT, LABEL, ATTRIB, CARDS, DATALINES wirksam und alle benötigten Variablen werden definiert und deklariert. Dabei werden für jede Variable ihre Eigenschaften festgelegt: Name (Ab Version 8 ist die Groß-/Kleinschreibung bei der Definition maßgeblich für die Speicherung), Typ (numerisch, alphanumerisch), Länge (in Bytes), Label, Format, Informat, und ob die Variable im Data Step temporär (Drop) oder permanent (Keep) ist. Für jede Variable wird im Arbeitsspeicher, im sogenannten Program data vector = PDV entsprechender Speicherplatz reserviert. Zusätzlich werden die Variablen _N_ und _ERROR_ erzeugt, welche für die Verwaltung benötigt werden und nur während der Ausführungsphase (temporär) zur Verfügung stehen. Sie werden nicht mit der Tabelle gespeichert. Mit _N_ werden alle Beobachtungen fortlaufend nummeriert und damit eindeutig identifiziert. _ERROR_ dient als Fehlerflag, welches die Werte 0 (fehlerfrei) und 1 (fehlerhaft) haben kann. SAS Programmierung für Fortgeschrittene I, Stürzl, Januar 08/SASFRT1.DOC Seite 5 von 59 DATA STEP Programmierung 1. Grundlagen des Datenschritts Beispiel 1: Namen und Geburtsdaten einiger Schauspieler OPTIONS YEARCUTOFF=1900; * zum korrekten Einlesen von zweistelligen Jahreszahlen im Bereich 1900 - 19992; DATA kino; INFILE DATALINES; * Datenquelle; INPUT Vorname $ Nachname:$12. GebDatum:DDMMYY8. Sex:$1.; Name=vorname||nachname; Alter=(TODAY() - gebdatum)/365.25;3 DATALINES; Benno Dustin Franka Gérard Götz Marlene RUN; Fürmann Hoffmann Potente Depardieu George Dietrich 17.01.71 08.08.37 22.07.74 27.12.48 23.07.38 27.12.01 1 1 2 1 1 2 PDV von WORK.KINO Vorname $8. Alter 8. Nachname $12. _N_ GebDatum Sex 8. $1. Name $20. _ERROR_ 2 HINWEIS zum Jahr 2000 Problem: Intern werden im SAS System Jahreszahlen immer korrekt gespeichert und können über verschiedene Formate angezeigt werden. Probleme können ausschließlich beim Einlesen von zweistelligen Jahreszahlen aus Nicht-SAS Dateien auftreten. Die Jahresangabe "02" zum Beispiel ist nicht eindeutig, weil die Angabe des Jahrhunderts fehlt. SAS bietet dazu die Option yearcutoff=jahreszahl; mit der eine 100-Jahres-Spanne ab Jahreszahl definiert wird. Beispiel: Yearcutoff=1900 interpretiert 00 - 99 als 1900 - 1999 (Voreinstellung in Version 6.12) Yearcutoff=1920 interpretiert 20 - 99 als 1920 - 1999 und 00 - 19 als 2000 bis 2019 (Voreinstellung ab Version 8) 3 Hinweis zur Altersberechnung: Die Formel Alter=(TODAY()-gebdatum)/365.25; berechnet das Alter in mittleren Jahren als Gleitkommazahl, die auch wenn sie ganzzahlig gemacht wird (z. B. durch Rundung oder Abschneiden der Nachkommastellen) nicht in allen Fällen mit der gebräuchlichen Alterszählweise übereinstimmt, wonach das Alter genau am Geburtstag um eins erhöht wird. Die folgende Formel löst das Problem und benutzt die Funktion INTCK (interval check) zur Zählung der Monate und die Eigenschaft, dass das Ergebnis eines Vergleichs in SAS eine Zahl ist (1 = wahr, 0 = falsch). Alter=FLOOR((INTCK('MONTH', gebdatum, TODAY()) - (DAY(TODAY()) < DAY(gebdatum)) )/12); SAS Programmierung für Fortgeschrittene I, Stürzl, Januar 08/SASFRT1.DOC Seite 6 von 59 DATA STEP Programmierung 1. Grundlagen des Datenschritts 1.2. Ausführungsphase Wenn die Kompilierung fehlerfrei war, kommt der Datenschritt zur Ausführung, wobei er automatisch für jede einzelne Beobachtung ausgeführt wird. Während dieser sogenannten Impliziten DO-Schleife, die sich nacheinander über alle Beobachtungen erstreckt, werden jeweils folgende vier Schritte durchgeführt. 1. Initialisierung aller Variablen Gibt es weitere Datenzeilen? nein Datei schließen ja _N_+ 1 2. Datenzeile einlesen 3. Ausführbare Anweisungen in der gegebenen Reihenfolge abarbeiten 4. Beobachtung in die Datei schreiben Implizite-DO-Schleife als Flussdiagramm 1. Initialisierung aller Variablen: _N_ wird am Anfang auf 1 gesetzt. _ERROR_ = 0. Neu entstehende Variablen, die durch die INPUT Anweisung oder durch Zuweisung erzeugt werden, werden mit Missing Value initialisiert (Ausnahme: RETAIN, siehe 1.6 RETAIN und SUM Anweisung, Seite 12). Variablen, die mit SET, MERGE oder UPDATE aus einer bestehenden SAS Tabelle gelesen werden, behalten im PDV die Werte der vorangehenden Beobachtung („autoretain“). Ausnahme: Nur beim By-Gruppenwechsel und bei _N_=1 wird ebenfalls mit Missing Value initialisiert (siehe 5.3. By-Gruppen Verarbeitung (byprocessing) mit SET und MERGE S. 40). 2. Nächste Datenzeile lesen mit der Anweisung SET, MERGE oder UPDATE aus einer bestehenden SAS Tabelle oder mit der Anweisung INPUT aus einer externen (Nicht-SAS) Datei bzw. aus eingebetteten Datenzeilen (DATALINES|CARDS) 3. Ausführbare Anweisungen (executable statements) werden in der gegebenen Reihenfolge abgearbeitet 4. Aktuellen Inhalt des PDV als eine Beobachtung in der(den) Tabelle(n) speichern (OUTPUT) Danach erfolgt ein Rücksprung zum Anfang des Datenschritts, wobei die Variable _N_ um eins erhöht wird. Die Schritte 1. bis 4. werden solange wiederholt, bis keine weiteren Datenzeilen mehr gelesen werden können. SAS Programmierung für Fortgeschrittene I, Stürzl, Januar 08/SASFRT1.DOC Seite 7 von 59 DATA STEP Programmierung 1. Grundlagen des Datenschritts 1.3. OUTPUT und DELETE Das (physikalische) Schreiben der Daten in die Tabelle, welches normalerweise am Ende des Datenschritts automatisch erfolgt, kann mit Hilfe der OUTPUT Anweisung auch schon vorher erzwungen werden. Damit lassen sich gezielt neue Beobachtungen erzeugen. Dafür entfällt das automatische OUTPUT am Ende, wodurch alle nachfolgenden Anweisungen dann zwar noch ausgeführt, die von ihnen bewirkten Datenänderungen aber nicht mehr gespeichert werden. Beispiel 2: Die Daten der Frauen und Männer in getrennten Tabellen speichern. Wie viele Variablen sind enthalten? DATA frauen maenner; SET kino; IF sex="1" THEN OUTPUT maenner; ELSE IF sex="2" THEN OUTPUT frauen; nr=_N_; RUN; Das Gegenteil der Output Anweisung bewirkt die DELETE Anweisung, mit der Beobachtungen gelöscht werden können. Durch die Delete Anweisung wird die Abarbeitung der aktuellen Beobachtung abgebrochen und - ohne die Beobachtung zu schreiben - mit der nächsten Beobachtung fortgesetzt (siehe „Selektion von Beobachtungen“). Beispiel 3: Die Daten der Männer löschen. DATA frauen; SET kino; IF sex="1" THEN DELETE; RUN; SAS Programmierung für Fortgeschrittene I, Stürzl, Januar 08/SASFRT1.DOC Seite 8 von 59 DATA STEP Programmierung 1. Grundlagen des Datenschritts 1.4 Automatische Datengenerierung Wenn in einem Datenschritt weder mit INPUT noch mit SET, MERGE, UPDATE Daten eingelesen werden, so stellt dies einen Sonderfall der Impliziten DO-Schleife dar, da sie nur einmal durchlaufen wird. Beispiel 4: DATA neu; X=1; RUN; Beispiel 5: Explizite DO-Schleife DATA neu; DO x=1 TO 10; nr=_N_; OUTPUT; * beendet und erzeugt eine Beobachtung; END; RUN; Beispiel 6: Explizite DO-Schleife DATA ertrag; Zins=5; Kapital=1000; DO Jahr=1 TO 5; kapital=kapital + kapital*zins/100; OUTPUT; END; RUN; PROC PRINT DATA=ertrag; RUN; Ö OBS 1 2 3 4 5 Zins 5 5 5 5 5 Kapital 1050.00 1102.50 1157.63 1215.51 1276.28 Jahr 1 2 3 4 5 SAS Programmierung für Fortgeschrittene I, Stürzl, Januar 08/SASFRT1.DOC Seite 9 von 59 DATA STEP Programmierung 1. Grundlagen des Datenschritts Beispiel 7: Erzeugen von zwei Dateien (Explizite DO-Schleife) DATA gerade ungerade; DO i=1 TO 1000; IF MOD(i,2)=0 THEN OUTPUT gerade; ELSE OUTPUT ungerade; END; RUN; Ö The data set WORK.GERADE has 500 observations and 1 variables. The data set WORK.UNGERADE has 500 observations and 1 variables Übung11a: Wie lässt sich folgende Tabelle a1 erzeugen? a1 x1 1 2 3 ... 20 x2 10 20 30 ... 200 x3 11 22 33 ... 220 x4 0.5 1.5 2.5 ... 19.5 x5 MOD(x1,2) SAS Programmierung für Fortgeschrittene I, Stürzl, Januar 08/SASFRT1.DOC Seite 10 von 59 DATA STEP Programmierung 1. Grundlagen des Datenschritts 1.5 Data Step Debugger Mit Hilfe des Data Step Debugger lässt sich die Ausführungsphase eines Data Steps schrittweise verfolgen. DATA tabelle1 <tabelle2...> / DEBUG; Der Aufruf erfolgt durch Ausführen eines Datenschritts mit der DEBUG Option der DATA Anweisung. Dadurch werden zwei neue Fenster geöffnet, die zur besseren Übersicht möglichst untereinander angeordnet werden sollten: 1. Debugger Log: Dient der Eingabe von Debugger Kommandos (in der letzten Zeile) und zeigt ihre Ergebnisse 2. Debugger Source: Zeigt den Data Step Quellcode und die jeweils aktuelle Zeile. Debugger Kommandos Debugger Kommando Beispiel ENTER Taste Bedeutung Nächste ausführbare Anweisung ausführen (= STEP 1). E(xamine) varlist | _all_ exy e _all_ Aktuellen Inhalt der Variablen x, y anzeigen Aktuellen Inhalt aller Variablen im PDV anzeigen ( PUT _ALL_) W(atch) varlist wxy Eine oder mehrere Variablen unter Beobachtung stellen. Jede Änderung wird automatisch angezeigt B(reak) line-number | label <AFTER count> <WHEN (expression)> <DO group > b 10 b 10 after 5 b 10 when (x=0) b 10 when (x=0) do; e x y; end; Breakpoint definieren bei Zeilennr. oder Data Step Label. Breakpoint bei Zeile 10 Breakpoint bei Zeile 10 nach ihrer 5. Ausführung Breakpoint bei Zeile 10 wenn Variable x=0 dito, zeige die Variablen x und y G(o) <line-number | label> go Anweisungen ausführen bis zum nächsten Breakpoint oder zur nächsten Änderung einer Watch-Variable D(elete) W(atch) varlist | _all_ d w _all_ Beobachtungsstatus für alle Watch-Variablen zurücknehmen D(elete) B(reak) line-number | label | _all_ d b _all_ Alle Breakpoints zurücknehmen St(ep) st 3 Die nächsten 3 Anweisungen ausführen ENTER <command-1 <... ; command-n>> enter st 3; e x y Der ENTER Taste die Kommandos „STEP 3 und EXAMINE x y“ zuweisen Desc(ribe) varlist | _all_ desc _all_ Attribute (Typ, Länge…) aller Variablen anzeigen L(ist) W | B | DATASETS | FILES | INFILES | _all_ lw lb l _all_ Alle Watch-Variablen auflisten Alle Breakpoints auflisten Alle Watch-Variablen, Breakpoints, SAS Tabellen, Output und Input Dateien auflisten Q(uit) q Debugger Modus und Data Step beenden Für eine vollständige Übersicht siehe SAS Help and Documentation Î SAS Products Î Base SAS Î SAS Language Dictionary Î Appendixes Î DATA Step Debugger SAS Programmierung für Fortgeschrittene I, Stürzl, Januar 08/SASFRT1.DOC Seite 11 von 59 DATA STEP Programmierung 1. Grundlagen des Datenschritts 1.6 RETAIN und SUM Anweisung Die RETAIN Anweisung (Deklarationsanweisung) verhindert die Initialisierung mit missing value bei der nächsten Beobachtung bei Variablen, die durch INPUT gelesen oder durch Zuweisung entstanden sind. Statt dessen wird die Ausprägung der vorangehenden Beobachtung übernommen und somit von einer Beobachtung zur nächsten weitergegeben ("vererbt"), bis ein neuer Wert zugewiesen wird. Syntax RETAIN variablenliste1 <initialwert1|(initialwert1)|(liste von initialwerten)> <variablenliste2...> Beispiele: RETAIN x y z; * initialisiert x, y, z mit missing value; RETAIN x y 10; * initialisiert x und y mit 10; RETAIN x y (10); = RETAIN x (10) y; RETAIN x y (10 100); = RETAIN x (10) y (100); RETAIN x1-x5 1 a b c "xyz"; RETAIN x1-x5 (1) a b c ("xyz"); * alle Variablen außer x1 und a sind mit missing value initialisiert!; Die SUM Anweisung eignet sich zur Addition von Datenwerten über Beobachtungen hinweg. Die Variable wird automatisch mit 0 initialisiert und erhält ein automatisches Retain. WICHTIG: Fehlende Werte (missing values) werden in der Summenbildung ignoriert. Syntax variable + ausdruck; variable + (-ausdruck); * Subtraktion; SAS Programmierung für Fortgeschrittene I, Stürzl, Januar 08/SASFRT1.DOC Seite 12 von 59 DATA STEP Programmierung 1. Grundlagen des Datenschritts Beispiel 8: Summenbildung DATA werte; DO i=1 TO 8; IF i=5 THEN x=.; ELSE x=i; OUTPUT; END; RUN; DATA summe; SET werte; RETAIN jahr 1990 sum1 0; jahr+1; * Sum Anweisung; sum1=sum1+x; sum2+x; * Sum Anweisung; PUT _ALL_; RUN; Ö I=1 I=2 I=3 I=4 I=5 I=6 I=7 I=8 X=1 X=2 X=3 X=4 X=. X=6 X=7 X=8 JAHR=1991 JAHR=1992 JAHR=1993 JAHR=1994 JAHR=1995 JAHR=1996 JAHR=1997 JAHR=1998 SUM1=1 SUM1=3 SUM1=6 SUM1=10 SUM1=. SUM1=. SUM1=. SUM1=. SUM2=1 SUM2=3 SUM2=6 SUM2=10 SUM2=10 SUM2=16 SUM2=23 SUM2=31 !!! Beispiel 9: LOCF (Last observation carry forward) Letzte non-missing Ausprägung fortschreiben. DATA locf; SET summe; RETAIN ergebnis; IF sum1^=. THEN ergebnis=sum1; PUT i= sum1= ergebnis=; RUN; Ö I=1 I=2 I=3 I=4 I=5 I=6 I=7 I=8 SUM1=1 SUM1=3 SUM1=6 SUM1=10 SUM1=. SUM1=. SUM1=. SUM1=. ERGEBNIS=1 ERGEBNIS=3 ERGEBNIS=6 ERGEBNIS=10 ERGEBNIS=10 ERGEBNIS=10 ERGEBNIS=10 ERGEBNIS=10 Beispiel 10: Reihenfolge der Variablen in einer Tabelle nachträglich ändern (Zweckentfremdung der RETAIN Anweisung). DATA kino; RETAIN Name Alter GebDatum; SET kino; * siehe Beispiel 1; RUN; Ö Neue Reihenfolge der Variablen: Name Alter GebDatum Vorname Nachname Sex SAS Programmierung für Fortgeschrittene I, Stürzl, Januar 08/SASFRT1.DOC Seite 13 von 59 DATA STEP Programmierung 1. Grundlagen des Datenschritts 1.7 LAG und DIF Funktion Die LAG Funktion ermittelt für eine Variable den Datenwert des n-ten Vorgängers und erlaubt damit Vergleiche über Beobachtungen hinweg. LAGn(variable) liefert die Ausprägung von variable n Beobachtungen vorher. Wenn n nicht angegeben wird, gilt n=1. Durch die Funktion wird ein temporäres Array aus n Elementen gebildet, welches mit missing values initialisiert und bei jedem neuen Aufruf dieser Funktion aktualisiert wird. Vorsicht bei bedingter Ausführung! Beispiel 11: DATA a; SET gerade; * Gerade Zahlen, siehe Beispiel 7, S. 10; x1=LAG1(i); x2=LAG2(i); IF MOD(i,4)=0 THEN x3=LAG1(i); IF MOD(i,4)=0 THEN x4=LAG2(i); RUN; Ö I 2 4 6 8 10 12 14 16 18 20 ... X1 X2 X3 X4 . 2 4 6 8 10 12 14 16 18 . . 2 4 6 8 10 12 14 16 . . . 4 . 8 . 12 . 16 . . . . . 4 . 8 . 12 Ähnliches gilt für die Funktion DIFn(variable), welche direkt die Differenz zum n-ten Vorgänger einer Variable berechnet. DIFn(variable) = variable - LAGn(variable). Beispiel 12: DATA a; INPUT x @@; x1=LAG1(x); d1=DIF1(x); x2=LAG2(x); d2=DIF2(x); DATALINES; 1 5 10 8 RUN; Ö x x1 d1 x2 d2 1 5 10 8 . 1 5 10 . 4 5 -2 . . 1 5 . . 9 3 SAS Programmierung für Fortgeschrittene I, Stürzl, Januar 08/SASFRT1.DOC Seite 14 von 59 DATA STEP Programmierung 1. Grundlagen des Datenschritts Übung11b: Fortsetzung der Übung11a, in der die folgende Tabelle a1 generiert worden ist. a1 x1 1 2 3 ... 20 x2 10 20 30 ... 200 x3 11 22 33 ... 220 x4 0.5 1.5 2.5 ... 19.5 x5 MOD(x1,2) Wie lässt sich folgende Tabelle a2 aus der Tabelle a1 erzeugen? a2 x1 1 2 3 4 5 6 ... 19 20 id 1 1 3 3 5 5 ... 19 19 Übung12: Tabelle a2 kann als Tabelle mit Messwerten der Größe X1 betrachtet werden. Für jede ID gibt es genau zwei Werte für die Größe X1. Berechnen Sie den Mittelwert von X1 pro ID (ohne Verwendung von Prozeduren) und bilden Sie jeweils die Differenz zu dem Wert von ID. Übung13: Optional Erzeugen Sie eine Normalgewichtstabelle für die Körperlängen von 1.50 m bis 2.00 m in Zentimeterschritten, wobei aus dem Body Mass Index von 19 und 25 kg/m² über die Formel Gewicht = BMI ⋅ Lä nge2 das jeweilige Minimal- und Maximalgewicht in kg berechnet wird. SAS Programmierung für Fortgeschrittene I, Stürzl, Januar 08/SASFRT1.DOC Seite 15 von 59 DATA STEP Programmierung 2. Tabellenoptionen (data set options) 2. Tabellenoptionen (data set options) Tabellenoptionen (data set options) sind optionale Angaben zu einer SAS Tabelle (data set). Sie können überall dort verwendet werden, wo der Name einer Tabelle steht, z. B. im Datenschritt in der DATA oder SET Anweisung und im Prozedurschritt. Tabellenoptionen werden in Klammern hinter dem Tabellennamen angegeben. Syntax: (option1= <option2= ...>) Tabellenoptionen unterscheiden sich von Anweisungen dadurch, dass sie in Klammern eingeschlossen sind, kein Semikolon benötigen und nach dem Schlüsselwort der Option immer ein Gleichheitszeichen (=) folgt. Für eine vollständige Übersicht siehe SAS Help and Documentation Î SAS Products Î Base SAS Î SAS Language Dictionary Î Dictionary of Language Elements Î SAS Data Set Options Eine Auswahl einiger wichtiger Tabellenoptionen: 1. Bestimmte Variablen auswählen (KEEP=) oder ausschließen (DROP=) (KEEP=variablenliste) (DROP=variablenliste) variablenliste ist dabei eine Aufzählung von Variablen, wobei verschiedene Kurzschreibweisen zulässig sind. z. B. (KEEP=x y nr1-nr5) x y nr1 nr2 nr3 nr4 nr5 (KEEP=hilf:) alle Variablen, deren Name mit "hilf" beginnt (KEEP=vorname--sex) bezogen auf die Reihenfolge der Variablen in der Tabelle (KEEP=_NUMERIC_) alle numerischen Variablen (KEEP=_CHARACTER_) alle alphanumerischen Variablen 2. Bestimmte Variablen umbenennen (RENAME=()) (RENAME=(alter_name1=neuer_name1 <alter_name2=neuer_name2...> <alt1-alt10=neu1-neu10>)) 3. Bestimmte Beobachtungen auswählen (WHERE=(), FIRSTOBS=, OBS=) (WHERE=(Bedingung)) (FIRSTOBS=n) (OBS=n) erste zu verarbeitende Beobachtung letzte zu verarbeitende Beobachtung Hinweise: Falls Optionen dieser 3 Gruppen zusammen verwendet werden, werden sie in dieser Reihenfolge wirksam. Es gilt: KEEP=/DROP= vor RENAME=() vor WHERE=()/FIRSTOBS=/OBS= Falls die WHERE= Option oder die WHERE Anweisung zusammen mit der FIRSTOBS= oder OBS= Option verwendet wird (erst ab SAS Version 8e möglich), so wird die Where Bedingung zuerst ausgeführt und ein temporäres Subset gebildet, auf dessen Beobachtungen sich dann FIRSTOBS= bzw. OBS= beziehen. Es gilt: WHERE=() vor FIRSTOBS=/OBS= Beispiel 13: Tabellenoption OBS= und WHERE (siehe Beispiel 1, Seite 6) PROC PRINT DATA=kino (OBS=1 WHERE=(sex="2")); RUN; ÖDaten der ersten Frau SAS Programmierung für Fortgeschrittene I, Stürzl, Januar 08/SASFRT1.DOC Seite 16 von 59 DATA STEP Programmierung 2. Tabellenoptionen (data set options) Beispiele: DATA neu; SET sashelp.class (WHERE=(alter>14) RENAME=(age=alter) KEEP=age); RUN; DATA neu (WHERE=(alter>14) RENAME=(age=alter) KEEP=age); SET sashelp.class; RUN; DATA neu; MERGE stamm (RENAME=(patno=patid)) labor (RENAME=(patient=patid)); BY patid; RUN; DATA deutsch (RENAME=(age=alter)) engl (RENAME=(name=firstname)); SET sashelp.class (KEEP=name age); RUN; DATA neu; SET werte1 (WHERE=(x>100)) werte2 (WHERE=(y>100)); RUN; PROC FREQ DATA=sashelp.class NOPRINT; TABLES age / OUT=stat1 (RENAME=(COUNT=anzahl) DROP=PERCENT WHERE=(anzahl>1)); RUN; PROC SORT DATA=sashelp.class (OBS=3) WHERE sex="F"; BY age; RUN; PROC SORT DATA=sashelp.class WHERE sex="F"; BY age; RUN; OUT=class (KEEP=name age); OUT=class (OBS=3 KEEP=name age); SAS Programmierung für Fortgeschrittene I, Stürzl, Januar 08/SASFRT1.DOC Seite 17 von 59 DATA STEP Programmierung 3. Selektion von Beobachtungen (IF, WHERE, DELETE) 3. Selektion von Beobachtungen (IF, WHERE, DELETE) In vielen Fällen wird eine Teilmenge von Beobachtungen einer Tabelle gesucht, die eine bestimmte Bedingung erfüllen. Die Bildung einer Teilmenge (subset) kann im Datenschritt mit den Anweisungen IF, WHERE oder DELETE erfolgen, im Prozedurschritt ausschließlich mit der WHERE Anweisung, oder in beiden Fällen mit der Tabellenoption WHERE= (siehe 2. Tabellenoptionen (data set options) S. 16). Mit der DELETE Anweisung lassen sich bestimmte Beobachtungen aus einer Tabelle löschen. Alle nachfolgenden Anweisungen werden dann für diese Beobachtungen übersprungen und SAS beginnt mit der nächsten Beobachtung Syntax: IF bedingung THEN DELETE; Eine IF Anweisung ohne nachfolgendes "then" wird als "Subsetting If" bezeichnet. Es bewirkt, dass die Abarbeitung nachfolgender Anweisungen im Datenschritt nur bei den Beobachtungen fortgesetzt wird, welche die Bedingung erfüllen. Im anderen Fall werden alle nachfolgenden Anweisungen (inkl. OUTPUT) übersprungen, die Beobachtung wird nicht in die Tabelle geschrieben und SAS beginnt mit der nächsten Beobachtung. Syntax: IF bedingung; IF NOT (bedingung) THEN DELETE; führt zum selben Ergebnis Die WHERE Anweisung (Deklarationsanweisung) kann im Datenschritt nur in Verbindung mit den beiden Anweisungen SET und MERGE verwendet werden. Sie ist vergleichbar einem View auf die genannte(n) Tabelle(n), so dass die Daten vorselektiert werden. Die Selektion wird vor dem Einlesen der Daten in den Program data vector (PDV) ausgeführt und kann deshalb nur einmal im Datenschritt verwendet werden. Syntax: WHERE bedingung; Beispiel 14: Selektion mit WHERE Anweisung DATA maenner; SET alle; WHERE sex="1"; RUN; Beim Einlesen mehrerer Tabellen wird die Bedingung auf alle genannten Tabellen angewendet. Um für einzelne Tabellen unterschiedliche Bedingungen anzuwenden, eignet sich die WHERE= Tabellenoption (siehe 2. Tabellenoptionen (data set options) S. 16). Subsetting IF ausschließlich im Datenschritt (ausführbare Anweisung) ⇒ Abfrage im PDV (Program data vector) Alle Observations werden eingelesen ⇒ Abfrage an beliebiger Stelle im Datenschritt Mehrmalige Verwendung möglich ⇒ Temporäre Variablen wie _N_, FIRST.-, LAST.-, IN= Variable in Abfrage erlaubt WHERE Im Datenschritt (mit SET oder MERGE) und im Prozedurschritt (Deklarationsanweisung) ⇒ Abfrage vor dem Einlesen in den PDV (schneller!) ⇒ einmalige Abfrage am Anfang des Step (View auf die Daten) ⇒ keine temporären Variablen in Abfragen (vor dem Einlesen noch nicht vorhanden) Besondere Operatoren BETWEEN, CONTAINS, LIKE SAS Programmierung für Fortgeschrittene I, Stürzl, Januar 08/SASFRT1.DOC Seite 18 von 59 DATA STEP Programmierung 3. Selektion von Beobachtungen (IF, WHERE, DELETE) Formulierung von Bedingungen Eine Bedingung kann ein Vergleich sein, ein logischer Ausdruck (mit den Operatoren NOT, AND, OR), ein Funktionsergebnis, ein Datenwert oder eine beliebige Kombination davon. Das Ergebnis einer Bedingung wird im SAS System als Zahl interpretiert. Die Bedingung gilt als nicht erfüllt (falsch, false), wenn der Wert 0 ist oder fehlt (Ausprägung 'missing value'). In allen anderen Fällen gilt die Bedingung als erfüllt (wahr, true), d.h. bei allen von 0 und missing value verschiedenen numerischen Werten. Beispiele für Vergleiche Beschreibung IF sex=1; IF UPCASE(antwort)="JA"; gleich IF gruppe^=""; IF wert^=.; ungleich IF gebdatum<"01may99"D; kleiner als das eingegebene Datum IF uhrzeit>="12:00"T; größer oder gleich dem angegebenen Zeitpunkt IF name=:"Me"; beginnt mit "Me" äquivalent zu IF IF name^=:"Me"; beginnt nicht mit "Me" äquivalent zu IF NOT name=:"Me"; IF name>=:"L"; beginnt mit "L" oder einem Buchstaben nach "L" z.B. L, M, N, ... IF MOD(_N_,2)=0; nur die geradzahligen Beobachtungen SUBSTR(name,1,2)="Me"; Beispiele für logische Ausdrücke (Prioritäten Reihenfolge: NOT, AND, OR) IF gewicht>=70 AND laenge<=1.70; beide Bedingungen müssen erfüllt sein IF 1.70<=laenge<1.80; wert liegt im Intervall 1.70 und 1.80 (AND) IF NOT (gewicht>=70 AND laenge<=1.70); beide Bedingungen dürfen nicht gleichzeitig erfüllt sein IF gewicht<70 OR laenge>1.70; mindestens eine der beiden Bedingungen muss erfüllt sein IF datum=TODAY() AND (land="D" OR land="F"); Klammerausdruck wird zuerst ausgeführt. Anschließend die ANDVerknüpgung. (Normalerweise hat "AND" Priorität vor "OR") IF nr IN (1 3 7); äquivalent zu: IF nr=1 OR nr=3 OR nr=7; IF name IN: ("L" "P"); beginnt mit "L" oder mit "P" äquivalent zu: IF name=:"L" OR name=:"P"; oder IF SUBSTR(name,1,1) IN ("L" P"); Beispiele für ein Funktionsergbnis als Bedingung IF MOD(_N_,2); nur die ungeradzahligen Beobachtungen (entspricht IF MOD(_N_,2) NOT IN (. 0);) IF INDEX(adresse, "@"); Enthält das Zeichen "@" IF MISSING(adresse); Enthält Missing Value (gilt für numerische und alphanumerische Variablen, sowie für spezielle missing value Zeichen). Ab V8 Beispiele für eine Kombination IF (laenge*100-100)/gewicht<1 AND sex="2"; Beispiele für eine Ausprägung einer Variablen als Bedingung IF FIRST.gruppe; Jeweils erste Beobachtung jeder Ausprägung der Variable, nach der die Tabelle sortiert ist. (BY Anweisung ist erforderlich.) SAS Programmierung für Fortgeschrittene I, Stürzl, Januar 08/SASFRT1.DOC Seite 19 von 59 DATA STEP Programmierung 3. Selektion von Beobachtungen (IF, WHERE, DELETE) Auswertungsreihenfolge von Operatoren Siehe SAS Help and Documentation Î SAS Products Î Base SAS Î SAS Language Concepts Î SAS System Concepts Î Expressions Î SAS Operators in Expressions Priorität Symbol I ** ^ ~ >< <> Mnemonic Bedeutung NOT MIN MAX Potenzierung Logisches Nicht Minimum Maximum II * / Multiplikation Division III + - Addition (falls Vorzeichen gilt Priorität I) Subtraktion (falls Vorzeichen gilt Priorität I) IV || !! Verknüpfung von Zeichenketten 4 V < <= = ^= ~= >= > LT LE EQ NE GE GT IN kleiner als kleiner oder gleich gleich ungleich größer oder gleich größer als gleich einem in der Liste (logisches Oder) VI & AND Logisches Und VII | ! OR Logisches Oder Vergleichsoperatoren, die nur für WHERE gelten Operator Bedeutung IS MISSING Missing Value (gilt für num. und alphanum. Variablen, sowie IS NULL spezielle missing value Zeichen) Between.. liegt zwischen .. und .. AND .. einschließlich CONTAINS enthält ? LIKE =* 4 Beispiel WHERE hausnr IS MISSING; äquivalent zu: WHERE MISSING(hausnr); Verneinung: WHERE hausnr IS NOT MISSING; WHERE hausnr BETWEEN 10 AND 20; äquivalent zu: WHERE 10<=hausnr<=20; WHERE hausnr CONTAINS "a"; WHERE hausnr ? "a"; Gleichheit mit Joker-Zeichen % steht für eine beliebige Anzahl WHERE name LIKE "Sch%z"; von Zeichen entspricht DOS * WHERE name LIKE "Sch_lz"; _ steht für genau ein Zeichen entspricht DOS ? WHERE name=*"Schulz"; klingt wie (sounds like) findet: Schulz, Schulze, Schuhlz, Scholz, Schalk, Sculx, Skuls nicht: Schultz, Schultze, Schulzer liefert phonetische Äquivalente indo-europäischer Sprachen nach dem Soundex Algorithmus von Odell und Russel (siehe SAS Technical Report P-222, Observations 1Q1997) Nach jedem Vergleichsoperator der Gruppe V kann beim Vergleich von Zeichenketten der Doppelpunkt (:) verwendet werden. Damit bezieht sich der Vergleich nur auf die ersten Zeichen. SAS Programmierung für Fortgeschrittene I, Stürzl, Januar 08/SASFRT1.DOC Seite 20 von 59 DATA STEP Programmierung 3. Selektion von Beobachtungen (IF, WHERE, DELETE) Boolesche Werte Boolesche Werte sind die Zahlen 0 für „Falsch“ (false) und 1 für „Wahr“ (true). Sie kommen vor als: Ergebnis eines Vergleichs Der Vergleich 1 < 5 ist wahr und liefert deshalb den Wert 1 Beispiel 15: Zählen von Ereignissen mit Hilfe Boolescher Werte. Wie viele der Variablen x1-x3 haben den Wert 0? summe=(x1=0) + (x2=0) + (x3=0); Beispiel 16: Bildung von Score-Punkten durch Gewichtung bestimmter Ereignisse. score= (alter > 45) + 2*(raucher=”ja”) + 3*(bmi > 25); Inhalt einer Booleschen Variable (numerische Variable mit dem Inhalt 0 oder 1) 1. Automatisch erzeugte Boolesche Variablen im Data Step • _ERROR_ gibt einen Hinweis auf Datenverarbeitungsfehler in einer Beobachtung. • FIRST. und LAST.Variablen kennzeichnen Beginn und Ende von By-Gruppen (siehe 5.3. By-Gruppen Verarbeitung (by-processing) mit SET und MERGE S. 40). • IN= Tabellenoption der SET und MERGE Anweisung erzeugt eine Boolesche Variable, die anzeigt, aus welcher Tabelle eine Beobachtung gelesen worden ist (siehe S. 35 bzw. 38). • END= Option der Anweisungen SET, MERGE, INFILE erzeugt eine Boolesche Variable, die anzeigt, ob die letzte Beobachtung erreicht ist (siehe S. 35 bzw. 38). 2. Selbst definierte Boolesche Variablen5 Beispiel 17: Kind=alter < 14; entspricht IF alter < 14 THEN Kind=1; ELSE Kind=0; 5 Falls Boolesche Variablen gespeichert werden, sollten sie die kleinstmögliche Länge numerischer Variablen haben (unter Windows die Länge 3 Byte), um Speicherplatz zu sparen. SAS Programmierung für Fortgeschrittene I, Stürzl, Januar 08/SASFRT1.DOC Seite 21 von 59 DATA STEP Programmierung 3. Selektion von Beobachtungen (IF, WHERE, DELETE) Numerischer Wert Jeder numerischer Wert kann als Boolescher Wert interpretiert werden, wobei die Werte 0 und missing value als „Falsch“, alle übrigen numerischen Werte – also alle positiven und negativen Zahlen –als „Wahr“ gelten. Beispiel 18: Division nur durchführen, wenn der Nenner ungleich Null ist. IF entfernung THEN durchschnitt=benzinverbrauch/entfernung; ELSE durchschnitt=.; Die Abfrage IF variable entspricht IF variable NOT IN (. 0). Ergebnis einer logischen Operation mit NOT, AND, OR Beispiel 19: Wahrheitstabelle von Booleschen Ausdrücken erstellen. DATA _NULL_; DO a=0,1; DO b=0,1; x=NOT (a AND b); y=NOT a OR NOT b; PUT a= b= x= y=; END; END; RUN; Ö a=0 a=0 a=1 a=1 b=0 b=1 b=0 b=1 x=1 x=1 x=1 x=0 y=1 y=1 y=1 y=0 Beispiel 20: Numerischen Wert in einen Booleschen Wert umwandeln. x=NOT(NOT(x)); SAS Programmierung für Fortgeschrittene I, Stürzl, Januar 08/SASFRT1.DOC Seite 22 von 59 DATA STEP Programmierung 3. Selektion von Beobachtungen (IF, WHERE, DELETE) Übung31: Warum scheitert die folgende Abfrage? Wie kann sie korrigiert werden? DATA neu; SET alt; WHERE _N_<=10; * Die ersten 10 Beobachtungen einlesen; RUN; Übung32: Welche Alternativen gibt es für folgenden Datenschritt? DATA frauen; SET kino; IF sex="1" THEN DELETE; RUN; Übung33: Welche Alternativen gibt es für folgende Abfragen? WHERE telefon=:"089" OR telefon=:"040"; WHERE antwort1="Nein" OR antwort1="nein" OR antwort1="NEIN"; Übung34: Formulieren Sie eine Selektionsbedingung, mit der aus einem Personenregister (ort, sex, gebdatum) alle vor 1920 geborenen Münchnerinnen und Hamburgerinnen gefunden werden. Übung35: Was bewirkt die folgende Abfrage? WHERE messdat<0; Übung36: Verneinen Sie die folgende Abfrage IF x=100 OR y=100; SAS Programmierung für Fortgeschrittene I, Stürzl, Januar 08/SASFRT1.DOC Seite 23 von 59 DATA STEP Programmierung 4. Einlesen von Daten aus externen Dateien 4. Einlesen von Daten aus externen Dateien SAS bietet vordefinierte Schnittstellen zu allen gängigen Datenbanken. Diese befinden sich jedoch nicht im Standardlieferumfang von Base SAS, sondern müssen gesondert lizenziert werden. Unabhängig davon können Dateien von SPSS und BMDP direkt über eine entsprechende Engine gelesen werden. Besonders vielseitige Möglichkeiten zum Einlesen bietet SAS für Daten, die im ASCII Format vorliegen. Umgekehrt lassen sich ASCII Dateien auch mit SAS erzeugen. Über DDE (Dynamic data exchange) besteht die Möglichkeit des Datenaustausches mit anderen Windows Anwendungsprogrammen, wie zum Beispiel Microsoft Excel, Word, Access. 4.1. Einlesen von Daten im ASCII-Format (INFILE, INPUT) Daten im ASCII Format können entweder in externen Dateien vorliegen oder aber - vor allem wenn es sich nur um wenige Daten handelt - mit der Anweisung DATALINES (oder CARDS) direkt im Quellcode des Programms integriert werden. Dies hat den Vorteil, dass nur eine einzige Datei benötigt wird und alle Informationen (Daten + Transaktionen) in der Programmdatei enthalten sind (s. Beispiel 1). Beim Einlesen aus externen Dateien wird dieselbe Syntax verwendet. Mit der INFILE Anweisung erfolgt der Hinweis auf die Datei, welche die Daten beinhaltet und mit der INPUT Anweisung wird diese Datei ausgelesen. Wie dies geschehen soll hängt davon ab, wie die Daten in der Datei angeordnet sind. Es ist zu unterscheiden, ob die Datenfelder in festen Spaltenpositionen stehen oder nur durch bestimmte Trennzeichen (delimiter) z.B. Blank unterschieden werden. In SAS werden drei Varianten unterschieden (column input, formatted input, list input), die sich beliebig kombinieren lassen. 1. Daten in festen Spaltenpositionen (column input, formatted input) Beispiel: ----|----10---|----20---|----30---|----40---|----50---|----60Benno Fürmann 17.01.71 1 1.85 79,0 Dustin Hoffmann 08.08.37 1 1.64 64,0 Franka Potente 22.07.74 2 1.74 62,0 Die gewünschten Daten können nun entweder durch Angabe der Spalten (column input) oder durch Angabe von geeigneten Einleseformaten und Positionierung des Pointers (formatted input) gelesen werden. Beispiel 21: column input INPUT name $ 1-30 gebdatum $ 31-38 sex 41 laenge 44-47 gewicht $ 5053; Beispiel 22: formatted input INPUT name $30. gebdatum DDMMYY8. @41 sex 1. @44 laenge 4.2 @50 gewicht COMMAX4.1; SAS Programmierung für Fortgeschrittene I, Stürzl, Januar 08/SASFRT1.DOC Seite 24 von 59 DATA STEP Programmierung 4. Einlesen von Daten aus externen Dateien Beide Methoden sind vergleichsweise mühsam, weil die Spaltenpositionen ausgezählt werden müssen. Bei der dritten Variante (list input) ist dies nicht notwendig, weil die Unterscheidung der Felder über ein einheitliches Trennzeichen (engl. delimiter) erfolgt. 2. Daten durch Trennzeichen unterscheidbar (list input) Voraussetzung hierfür ist ein einheitliches Trennzeichen, das mit der DLM= Option der INFILE Anweisung definiert wird (Voreinstellung ist Blank). Feste Spaltenpositionen sind hier nicht zwingend notwendig, aber möglich. Bis auf die Kennzeichnung von alphanumerischen Variablen durch ein nachgestelltes "$" sind keine Formatierungen notwendig, jedoch möglich (Informat kann mit ":" angehängt werden). Falls keine Formatierung erfolgt, gilt für numerische und alphanumerische Variablen die Standardlänge 8. Missing value ist auch für alphanumerische Variablen der Punkt. ACHTUNG: Einzulesende alphanumerische Variablen dürfen das Trennzeichen selbst nicht enthalten! Führende (leading), dazwischenliegende (embedded) und nachfolgende (trailing) Trennzeichen werden ignoriert. Unmittelbar aufeinanderfolgende Trennzeichen werden wie eines behandelt (Abschaltbar mit der DSD Option von INFILE). Beispiel 23: list input ohne Einleseformate INPUT vorname $ nachname $ gebdatum $ sex laenge gewicht $; Beispiel 24: list input mit Einleseformaten INPUT vorname $ nachname $ gebdatum:DDMMYY8. sex laenge gewicht:NUMX4.1; Gelesen wird ab der nächsten Spalte, welche das Trennzeichen nicht enthält, bis zum übernächsten Trennzeichen, jedoch höchstens bis zur vorgegebenen Länge des Einleseformates. ACHTUNG: INPUT name $30.; * liest immer 30 Zeichen (formatted input); INPUT name:$30.; * liest bis zum nächsten Trennzeichen, jedoch höchstens 30 Zeichen (list input); INPUT name $30 ; * liest genau 1 Zeichen aus Spalte 30 (column input); Der Nachteil des list input besteht darin, dass die Datenzeile als Ganzes gelesen und dann in einzelne Felder aufgeteilt wird, sodass die Felder in der vorgegebenen Reihenfolge gelesen werden müssen und keine Felder übersprungen werden können. Durch die gezielte Steuerung des Einlesezeigers mit "@" ist es möglich, dieselben Felder ggfs. mehrmals mit unterschiedlichen Informaten zu lesen oder zuerst ein bestimmtes Feld auszulesen und von seinem Inhalt das weitere Vorgehen abhängig zu machen. Beispiel 25: Nur bestimmte Daten einlesen INPUT @41 sex @; * @ hält Einlesezeiger in der Datenzeile!; IF sex=1 THEN INPUT @1 name $30. ELSE DELETE; SAS Programmierung für Fortgeschrittene I, Stürzl, Januar 08/SASFRT1.DOC @44 laenge gewicht:COMMAX4.1; Seite 25 von 59 DATA STEP Programmierung 4. Einlesen von Daten aus externen Dateien Übung41: Die Datei DIR.TXT ist eine automatisch erstellte Textdatei und stellt den Inhalt eines beliebigen Ordners unter Windows dar. (DOS Kommando: DIR > dir.txt) a.) Lesen Sie daraus Datum, Uhrzeit, Größe und Name der Dateien und Unterverzeichnisse und speichern Sie diese Informationen permanent in der SAS Tabelle "DIRLIST". Darin soll auch eine Variable enthalten sein, aus deren Inhalt hervorgeht, ob es sich um eine Datei oder ein Unterverzeichnis handelt. b.) Außerdem sollen Laufwerk und Name des gelisteten Ordners (C:\Program Files\SAS Institute) in jeder Beobachtung stehen und jedem Namen vorangestellt werden, so dass vollständige Pfadnamen entstehen. Beispiel: C:\Program Files\SAS Institute\autorun.inf ----|----10---|----20---|----30---|----40---|----50---|----60Datenträger in Laufwerk C: ist Sys Datenträgernummer: 3B04-AD5E Verzeichnis von C:\Program Files\SAS Institute 13.07.2004 01.08.2003 30.01.2001 15.07.2003 30.01.2001 15.07.2003 30.01.2001 30.01.2001 30.01.2001 30.01.2001 15.07.2003 30.01.2001 15.07.2003 30.01.2001 21.04.2004 15.07.2003 15.07.2003 30.01.2001 30.01.2001 15.07.2003 15.07.2003 12.01.2004 14:39 <DIR> . 10:35 <DIR> .. 13:00 147.728 asycfilt.dll 17:38 <DIR> autorun 13:00 331 autorun.inf 17:40 <DIR> bundles 13:00 12 cd1.id 13:00 18 cd101.id 13:00 18 cd102.id 13:00 23 cd901.id 17:41 <DIR> doc 13:00 1.384.448 msvbvm60.dll 17:41 <DIR> odbcdrv 13:00 942 readme.txt 13:41 <DIR> SAS 17:52 <DIR> sasview 17:52 <DIR> saw 13:00 126.976 setup.exe 13:00 11.173 setup.ini 17:53 <DIR> srw 17:53 <DIR> sscu 13:54 <DIR> HotFixes 10 Datei(en) 1.671.669 Bytes 12 Verzeichnis(se), 24.243.621.888 Bytes frei SAS Programmierung für Fortgeschrittene I, Stürzl, Januar 08/SASFRT1.DOC Seite 26 von 59 DATA STEP Programmierung 4. Einlesen von Daten aus externen Dateien 4.2. Einlesen von Daten aus Microsoft Excel Tabellen Zum Einlesen von Daten aus Microsoft Excel® Tabellen bieten sich in SAS zwei grundsätzlich verschiedene Wege. I. Lesen eines ganzen Blattes aus einer nicht geöffneten Excel Datei (PROC IMPORT, LIBNAME Anweisung mit EXCEL Option Ï Spaltenüberschriften können in Variablennamen übernommen werden. Ï Die unformatierten Werte werden in voller Genauigkeit gelesen. Ï Keine Abhängigkeit von der Excel Sprachversion und dem Dezimaltrennzeichen. Ð Geeignet vor allem für einheitlich strukturierte Tabellenblätter. Ð Lizenz für das Modul „SAS/ACCESS to PC file formats“ ist notwendig. II. Lesen eines rechteckigen Zellbereichs aus einer geöffneten Excel Datei (DDE) Ï Geeignet für beliebig strukturierte Tabellenblätter. Ï Funktionalität ist in Base SAS enthalten. ♦ Werte werden genauso gelesen wie sie in Excel angezeigt werden (aktuelle Formatierung). Ð Spaltenüberschriften können nicht in Variablennamen übernommen werden. Ð Abhängigkeit von der Excel Sprachversion und dem Dezimaltrennzeichen. 4.2.1 PROC IMPORT Mit Hilfe der SAS/ACCESS Prozedur IMPORT und der Engine EXCEL kann ein bestimmtes Tabellenblatt einer Excel Datei gelesen und als SAS Tabelle gespeichert werden. Alternativ kann auch der „Import Wizard“ über File Î Import Data... verwendet werden. Beispiel 26: PROC IMPORT DBMS=EXCEL DATAFILE="C:\Temp\Test.xls" OUT=work.test; SHEET='Tabelle1'; GETNAMES=NO; RUN; Einige Optionen der Engine EXCEL (Standard ist unterstrichen): • GETNAMES=YES|NO Legt fest, ob die Spaltenüberschrift als Variablennamen verwendet werden. • MIXED=NO|YES Legt fest, wie mit Zahlen in Spalten mit numerischen und alphanumerischen Werten umgegangen wird. NO: Zahlen werden als missing value dargestellt YES: Zahlen werden ins Characterformat konvertiert. • TEXTSIZE=1 to 32767 Legt die maximale Länge von Charactervariablen fest (Standard 1024). • SCANTEXT=YES|NO Legt fest, ob alle Zeilen einer Textspalte gelesen werden, um den längsten Text zu finden und damit die Länge der Charactervariable zu bestimmen. • SCANTIME=YES|NO Legt fest, ob alle Zeilen einer Spalte mit Datums- und Zeitwerten gelesen werden, um das Einleseformat zu bestimmen. • USEDATE=YES|NO Legt das Einleseformat für Datums- und Zeitwerte fest YES: DATE. Format NO: DATETIME. Format. Details siehe Online Hilfe zu PROC IMPORT. SAS Programmierung für Fortgeschrittene I, Stürzl, Januar 08/SASFRT1.DOC Seite 27 von 59 DATA STEP Programmierung 4. Einlesen von Daten aus externen Dateien 4.2.2 LIBNAME Anweisung mit EXCEL Option Mit Hilfe der SAS/ACCESS LIBNAME Anweisung und der Engine EXCEL kann eine Excel Datei referenziert werden, auf die SAS lesend und schreibend zugreifen kann (ab V9). Der Zugriff auf die enthaltenen Tabellenblätter erfolgt über die so definierte libref. Alternativ kann auch der „New Library“ Dialog zur Definition verwendet werden. Beispiel 27: LIBNAME meinxls EXCEL "C:\Temp\Test.xls" GETNAMES=NO; PROC MEANS DATA=meinxls."tabelle1$"N; RUN; DATA work.test; SET meinxls."tabelle1$"N; RUN; LIBNAME meinxls CLEAR; Falls der Name des Tabellenblattes nicht die SAS Namenskonvention erfüllt, muss er in Anführungszeichen gefolgt vom Buchstaben N gesetzt werden (SAS name literal) z.B. DATA=meinxls."Erste Tabelle$"N Optionen der Engine EXCEL siehe PROC IMPORT Beispiel 28: LIBNAME meinxls EXCEL "C:\Temp\Test.xls" GETNAMES=NO MIXED=YES; Beispiel 29: Daten von SAS nach Excel schreiben, indem eine neue Exceldatei mit dem Blatt ‚Klasse’ angelegt wird. LIBNAME xlsneu EXCEL "C:\Temp\Test2.xls"; DATA xlsneu.klasse; SET sashelp.class; RUN; Beispiel 30: Daten von SAS nach Excel schreiben, indem in einer bestehenden Exceldatei eines weiteres Blatt ‚Jungen’ angelegt wird. DATA xlsneu.jungen; SET sashelp.class; WHERE sex="M"; RUN; Details siehe Online Hilfe. SAS Programmierung für Fortgeschrittene I, Stürzl, Januar 08/SASFRT1.DOC Seite 28 von 59 DATA STEP Programmierung 4. Einlesen von Daten aus externen Dateien 4.2.3 DDE Mit Hilfe der INFILE Anweisung und der Option DDE (dynamic data exchange) in Base SAS wird eine Verbindung zu einem rechteckigen Zellbereich einer aktuell geöffneten Excel Tabelle (DDE Kanal) hergestellt. Darüber können Daten mit der INPUT Anweisung aus Excel gelesen oder mit der PUT Anweisung nach Excel geschrieben werden6. Allerdings ist dieser Weg nicht besonders komfortabel und besitzt einige Einschränkungen, die im folgenden beschrieben werden. • Die Excel Datei muss in Excel geöffnet sein. • Gelesen wird ein frei definierbarer rechteckiger Zellbereich der Excel Tabelle, aus dem die Daten genauso übernommen werden wie sie in Excel aktuell formatiert und angezeigt sind. • Wenn als Dezimaltrennzeichen in Excel das Komma verwendet wird, muss eine Konvertierung in den Punkt erfolgen z. B. mit Hilfe der Informate NUMX (ab Version 6.12) oder COMMAX. • Die SAS Syntax hängt von der Sprachversion des verwendeten Excel ab. Das nachfolgende Beispiel bezieht sich auf eine deutsche Excel Version. Beispiel 31: Aus der Exceldatei "C:\Temp\Test.xls" die Zellen von Zeile1 Spalte1 bis Zeile12 Spalte3 nach SAS einlesen (siehe nebenstehende Abbildung). Dabei leere Zellen korrekt als fehlende Werte (missing values) erkennen. Syntax 1 ohne Angabe des Tabellenblattes, wodurch automatisch das erste Tabellenblatt verwendet wird. FILENAME daten DDE 'EXCEL|c:\temp\test.xls!Z1S1:Z12S3'; Syntax 2 mit Angabe des Tabellenblattes FILENAME daten DDE 'EXCEL|c:\temp\[test.xls]Tabelle1!Z1S1:Z12S3'; DATA in; INFILE daten DLM='09'X NOTAB DSD MISSOVER; INFORMAT var1 $10. var2 NUMX.; INPUT var1 var2 var3; RUN; 6 Siehe SAS Help and Documentation Î Using SAS Software in Your Operating System Î Using SAS in Windows Î Using SAS with Other Windows Applications Î Using Dynamic Data Exchange under Windows, SAS Technical Support Documente TS325 "The SAS System and DDE", TS589b "Importing Excel files to SAS data sets", TS589c "Importing Microsoft Access tables to SAS Datasets" SAS Programmierung für Fortgeschrittene I, Stürzl, Januar 08/SASFRT1.DOC Seite 29 von 59 DATA STEP Programmierung 4. Einlesen von Daten aus externen Dateien Beispiel 32: SAS Output mit Hilfe von ODS HTML (Output Delivery System) nach MS Excel bringen (ab V8) SAS Output als HTML-Datei (mit der Dateiendung '.xls'!) ausgeben lassen, welche von Excel direkt gelesen werden kann (ab Excel 97). Durch Speichern der Datei in Excel wird das HTML-Format mit Excel Format überschrieben. FILENAME report1 'c:\temp\test2.xls'; ODS LISTING CLOSE; ODS HTML BODY=report1 STYLE=MINIMAL; PROC PRINT DATA=sashelp.class; RUN; PROC MEANS DATA=sashelp.class; RUN; ODS HTML CLOSE; ODS LISTING; Übung42: In der nachfolgend abgebildeten Excel Tabelle MESSTAB1.XLS sind für verschiedene IDs zu verschiedenen Zeitpunkten die Messergebnisse zweier Parameter von je vier verschiedenen Geräten dargestellt. Die Daten sind sortiert nach ID und Messdatum. Lesen Sie aus den Bereich von Zeile3 Spalte1 bis Zeile12 Spalte10 und erzeugen Sie eine permanente SAS Tabelle "MESSTAB1" ein (Leerzeilen löschen). ID Messdatum (jjmmtt) Parameter 1 Parameter 2 Gerät 1 Gerät 2 Gerät 3 Gerät 4 Gerät 1 Gerät 2 Gerät 3 Gerät 4 1/94 1/94 1/94 940124 940131 940407 0,3 0,8 8,6 5,5 5,5 2/94 2/94 2/94 2/94 2/94 2/94 940210 940211 940212 940213 940215 940216 0,1 0,1 0,1 0,0 0,1 0,0 0,1 0,2 0,4 0,5 1,0 1,1 7,0 7,4 7,4 12,1 9,2 6,9 60 72 80 0,6 0,8 0,8 0,8 0,9 0,5 0,5 0,8 0,9 1,4 1,4 82 60 50 85 80 65 SAS Programmierung für Fortgeschrittene I, Stürzl, Januar 08/SASFRT1.DOC 55 85 120 89 75 84 21 95 120 85 35 54 97 114 44 35 65 116 63 16 196 135 85 76 131 212 Seite 30 von 59 DATA STEP Programmierung 5. Verknüpfung von Tabellen (SET, MERGE) 5. Verknüpfung von Tabellen (SET, MERGE) Wenn die Daten bereits in SAS Tabellen (SAS data sets) vorliegen, kann über die Anweisungen SET oder MERGE auf diese lesend zugegriffen werden, wobei damit verschiedene Tabellen zu einer neuen Tabelle verknüpft werden können. Syntax: SET tabelle1 <tabelle2 ...> <END=var1> <NOBS=var2>; MERGE tabelle1 <tabelle2 ...><END=var1>; Beide Anweisungen erlauben das Lesen aus einer oder mehreren Tabellen. Für jede Tabelle können dabei Tabellenoptionen verwendet werden (siehe 2. Tabellenoptionen (data set options) S. 16). Falls mehrere Tabellen angegeben werden, so werden die Daten dieser Tabellen miteinander verknüpft, wobei verschiedene Varianten möglich sind. SET MERGE A A B B Mit der SET Anweisung werden Tabellen vertikal verknüpft, sodass zusätzliche Beobachtungen angefügt werden können. Dies ist sinnvoll für Tabellen mit verschiedenen Beobachtungen und denselben Variablen Mit der MERGE Anweisung werden Tabellen horizontal verknüpft, sodass zusätzliche Variablen angefügt werden können. Dies ist sinnvoll für Tabellen mit verschiedenen Variablen zu denselben Beobachtungen Für eine vollständige Übersicht siehe SAS Help and Documentation Î SAS Products Î Base SAS Î SAS Language Concepts Î DATA Step Concepts Î Reading, Combining, and Modifying SAS Data Sets SAS Programmierung für Fortgeschrittene I, Stürzl, Januar 08/SASFRT1.DOC Seite 31 von 59 DATA STEP Programmierung 5. Verknüpfung von Tabellen (SET, MERGE) Für die nachfolgenden Beispiele werden zur Veranschaulichung beispielhaft die beiden folgenden Tabellen EINS und ZWEI verwendet, welche unterschiedliche viele Beobachtungen, zwei übereinstimmende Variablen (ID, X) und jeweils eine weitere Variable besitzen. Beispieldateien: EINS ID X Y A B B C 1 2 2 3 10 20 20 30 ZWEI ID X Z B D 4 5 40 50 5.1 SET Die SET Anweisung liest eine Beobachtung aus einer oder mehreren Tabellen. Sie eignet sich dazu, an eine bestehende Tabelle weitere Beobachtungen anzuhängen (vertikale Verknüpfung). Syntax: SET tabelle1 <tabelle2 ...>; Im Falle mehrerer Tabellen werden zunächst alle Beobachtungen aus Tabelle1, dann aus Tabelle2 u. s. w. gelesen. Um eine Tabelle zu kopieren, genügt es diese allein anzugeben. Fall 1: Kopieren einer Tabelle DATA neu; SET alt; <weitere Anweisungen...> RUN; Nacheinander wird jede Beobachtung aus der bestehenden Tabelle WORK.ALT eingelesen, steht damit für eine weitere Verarbeitung zur Verfügung und wird schließlich im der neuen Datei WORK.NEU gespeichert. Es ist auch möglich, für die resultierende Tabelle denselben Namen zu verwenden, um z. B. in einer bestehenden Tabelle Änderungen vorzunehmen. Die SET Anweisung arbeitet dann mit einer temporären Kopie, welche am Ende das Original überschreibt. DATA alt; SET alt; <weitere Anweisungen...> RUN; Analog könnte hierfür auch die MERGE Anweisung verwendet werden. SAS Programmierung für Fortgeschrittene I, Stürzl, Januar 08/SASFRT1.DOC Seite 32 von 59 DATA STEP Programmierung 5. Verknüpfung von Tabellen (SET, MERGE) Fall 2: Hintereinanderhängen mehrerer Tabellen (concatenating) Wenn in einer SET Anweisung mehrere SAS Tabellen genannt werden, so entsteht eine neue Tabelle, welche unverändert alle Beobachtungen der ersten Tabelle, daran anschließend alle Beobachtungen der zweiten Tabelle u. s. w. enthält. Alle Einzeltabellen werden also in der angegebenen Reihenfolge vertikal miteinander verknüpft. Die Anzahl der Beobachtungen der Ergebnistabelle ist gleich der Summe der Beobachtungen der Einzeltabellen. Im Einzelnen sind folgende Dinge zu beachten: • Gemeinsame Variablen müssen in allen Tabellen vomselben Typ sein. Fehlermeldung: ERROR: Variable xxx has been defined as both character and numeric. • Gemeinsame Variablen sollten in allen Tabellen dieselbe Länge haben. Andernfalls ist die Länge der erstgenannten Datei maßgeblich. Wenn dies die kürzere ist, kann es zu Datenverlust kommen! Entsprechendes gilt auch für Label, Format und Informat der Variablen. • Haben die Einzeltabellen unterschiedliche Variablen, so enthält die resultierende Tabelle alle Variablen der Einzeltabellen, wobei an den entsprechenden Stellen fehlende Werte (missing values) auftreten. CONCAT: ID X Y Z A B B C B D 1 2 2 3 4 5 10 20 20 30 . . . . . . 40 50 DATA concat; SET eins zwei; RUN; Es ist auch möglich, dieselbe Tabelle mehrmals zu lesen. Auf diese Weise lassen sich die Daten einer Tabelle beliebig oft vervielfältigen, indem diese Tabelle in einer SET Anweisung entsprechend oft angegeben wird. ZWEIFACH: DATA zweifach; SET zwei zwei; RUN; ID X Z B D B D 4 5 4 5 40 50 40 50 Fall 3: Ineinander Sortieren mehrerer Tabellen (interleaving) Diese Variante der vertikalen Verknüpfung eignet sich, wenn die zu verknüpfenden Tabellen alle in derselben Weise sortiert sind, und diese Sortierung beim Verknüpfen erhalten bleiben soll. Dazu werden die gemeinsamen Schlüsselvariablen (By-Variablen), nach denen die Dateien sortiert sind in einer BY Anweisung angegeben. SETBY: DATA setby; SET eins zwei; BY id; RUN; SAS Programmierung für Fortgeschrittene I, Stürzl, Januar 08/SASFRT1.DOC ID X Y Z A B B B C D 1 2 2 4 3 5 10 20 20 . 30 . . . . 40 . 50 Seite 33 von 59 DATA STEP Programmierung 5. Verknüpfung von Tabellen (SET, MERGE) Fall 4: Mischen (Nebeneinander Setzen) mehrerer Tabellen (one-to-one reading) Sollen die Daten aus verschiedenen Tabellen nicht vertikal aneinander gehängt, sondern in jeweils einer Beobachtung einander gegenübergestellt (gemischt, "gemergt") werden, so kann dies dadurch erreicht werden, indem jede Tabelle mit einer eigenen Set Anweisung gelesen wird. Die resultierende Tabelle enthält alle Variablen der Einzeltabellen. Im Einzelnen sind folgende Dinge zu beachten: • Haben die Einzeltabellen übereinstimmende Variablen, so überschreiben die zuletzt genannten Tabellen die Variablenwerte der vorhergehenden! • Haben die Einzeltabellen unterschiedlich viele Beobachtungen (n1≠n2), so stoppt das Mischen, sobald die erste Tabelle zu Ende ist. Der Umfang der kleinsten Tabelle bestimmt den Umfang der resultierenden Tabelle. DATA setset1; SET eins; SET zwei; RUN; SETSET1: ID X Y Z B D 4 5 10 20 40 50 Fall 5: Eine Beobachtung mit vielen Beobachtungen verknüpfen (one-to-many merge) Sollen die Daten aus einer Beobachtung einer Tabelle in allen Beobachtungen einer anderen Tabelle verfügbar sein, so muss diese eine Beobachtung mit jeder Beobachtung der anderen Tabelle "gemergt" werden. Wenn dabei kein gemeinsames Verknüpfungsmerkmal, d. h. keine gemeinsame By-Variable vorhanden ist, kann dies mit Hilfe des automatischen RETAINs der SET Anweisung erreicht werden. Beispiel: Den Wert der Variable Z aus der ersten Beobachtung der Tabelle ZWEI (z=40) in allen Beobachtungen der Tabelle EINS verfügbar machen. SETSET2 DATA setset2; SET eins; IF _N_=1 THEN SET zwei; RUN; SAS Programmierung für Fortgeschrittene I Stürzl Januar 08/SASFRT1.DOC ID X Y Z B B B C 4 2 2 3 10 20 20 30 40 40 40 40 Seite 34 von 59 DATA STEP Programmierung 5. Verknüpfung von Tabellen (SET, MERGE) 5.1.1 Optionen der SET Anweisung END=variable Mit Hilfe der END Option der SET Anweisung lässt sich eine temporäre Variable erzeugen, die anzeigt, ob die letzte Beobachtung der genannten Tabellen gelesen wird (Wert=1) oder nicht (Wert=0). NEU: DATA neu; SET eins zwei END=letzter NOBS=anzahl; RUN; ID X Y Z A B B C B D 1 2 2 3 4 5 10 20 20 30 . . . . . . 40 50 letzter anzahl 0 0 0 0 0 1 6 6 6 6 6 6 NOBS=variable Mit Hilfe der NOBS Option der SET Anweisung lässt sich eine temporäre Variable erzeugen, welche die Summe der Beobachtungen aller genannten Tabellen enthält. Die Besonderheit liegt darin, dass diese Information in der Kompilierungsphase verfügbar ist, d.h. vor der Ausführung der SET Anweisung. Dadurch ist es möglich, die Anzahl der Beobachtungen einer/mehrerer Tabellen sehr schnell abzufragen, ohne deren Daten zu lesen. Beispiel 33: Anzahl der Beobachtungen einer oder mehrerer Tabellen in eine Makrovariable n schreiben. DATA _NULL_; CALL SYMPUT ('n',LEFT(PUT(anzahl, BEST.))); SET tabelle1 <tabelle2 ...> NOBS=anzahl; STOP; * Data-Step abbrechen; RUN; %PUT &n; * Makrovariable ausgeben; (IN=variable) Mit Hilfe der IN= Tabellenoption lässt sich eine temporäre Variable erzeugen, die anzeigt, ob die jeweilige Beobachtung aus der entsprechenden Tabelle stammt (Wert=1) oder nicht (Wert=0). CONCAT: DATA concat; SET eins (IN=ex1) zwei (IN=ex2); RUN; SAS Programmierung für Fortgeschrittene I Stürzl Januar 08/SASFRT1.DOC ID X Y Z ex1 ex2 A B B C B D 1 2 2 3 4 5 10 20 20 30 . . . . . . 40 50 1 1 1 1 0 0 0 0 0 0 1 1 Seite 35 von 59 DATA STEP Programmierung 5. Verknüpfung von Tabellen (SET, MERGE) 5.2. MERGE Die MERGE Anweisung eignet sich dazu, entsprechende Beobachtungen aus zwei oder mehreren Tabellen miteinander zu verknüpfen. Alle Einzeltabellen werden in der angegebenen Reihenfolge horizontal verknüpft. Syntax: MERGE tabelle1 <tabelle2 ...>; Fall 6: Match Merging (Gezieltes Mischen mit BY)7 Dies ist die "sicherste" Form des Mischen, weil die Verknüpfung kontrolliert erfolgen kann. Um sicherzustellen, dass ausschließlich einander entsprechende Beobachtungen miteinander verbunden werden, wird ein gemeinsames Verknüpfungsmerkmal benötigt. Dies sind eine oder mehrere Schlüsselvariablen (By-Variablen), die in allen zu verknüpfenden Tabellen vorkommen und wonach alle Einzeltabellen sortiert sind. Die gemeinsamen Schlüsselvariablen werden in einer BY Anweisung angegeben. Die Anzahl der Beobachtungen der resultierenden Tabelle ist die Summe der verschiedenen Ausprägungen der ByVariablen der Einzeltabellen. Im Einzelnen sind folgende Dinge zu beachten: • Die By-Variablen müssen in allen Tabellen vomselben Typ sein. Sonst erscheint folgende Fehlermeldung: ERROR: Variable xxx has been defined as both character and numeric. • Die By-Variablen sollten in allen Tabellen dieselbe Länge haben. Andernfalls ist die Länge der erstgenannten Datei maßgeblich. Wenn dies die kürzere ist, kann es zu Datenverlust und damit zu falschen Verknüpfungen kommen. WARNING: Multiple lengths were specified for the BY variable xxx by input data sets. This may cause unexpected results. • Die By-Variablen sollten in allen Tabellen in Label, Format und Informat übereinstimmen. Andernfalls sind die Attribute der erstgenannten Datei maßgeblich. • Die Verknüpfung sollte eindeutig sein, d.h. derselbe Schüssel darf höchstens in einer Tabelle mehrfach vorkommen (1:1 oder 1:n Verknüpfung). Andernfalls (m:n) erscheint folgender Hinweis im Log NOTE: MERGE statement has more than one data set with repeats of BY values. • Die Einzeltabellen sollten neben den By-Variablen keine weiteren gemeinsamen Variablen besitzen. Andernfalls überschreiben die Werte aus der letztgenannten Tabelle die Variablenwerte der vorhergehenden! Durch die Systemoption MSGLEVEL=I (info) wird zusätzlich zu Notes, Warnings und Errors in diesem Fall eine entsprechende Info im Log angezeigt. Standardeinstellung ist jedoch MSGLEVEL=N (note), wodurch keine Infos gegeben werden. INFO: The variable x on data set WORK.EINS will be overwritten by data set WORK.ZWEI. DATA mergeby; MERGE eins zwei; BY id; RUN; 7 MERGEBY: ID A B B C D X 1 4 2 3 5 Y 10 20 20 30 . Z . 40 40 . 50 Über die Systemoption MERGENOBY=WARN|ERROR erscheint im Log eine Warnung bzw. Fehlermeldung, wenn MERGE ohne BY Anweisung verwendet wird. Standardeinstellung ist MERGENOBY=NOWARN. SAS Programmierung für Fortgeschrittene I Stürzl Januar 08/SASFRT1.DOC Seite 36 von 59 DATA STEP Programmierung 5. Verknüpfung von Tabellen (SET, MERGE) Fall 7: One-to-One Merging (Mischen ohne BY)8 Im Gegensatz zu "One-to-one reading" bestimmt hier der Umfang der größten Einzeltabelle den Umfang der resultierenden Tabelle, das heißt, wenn einer der Einzeltabellen vorzeitig zu Ende geht, werden dafür missing values ergänzt. ACHTUNG: Haben die Einzeltabellen übereinstimmende Variablen, so überschreiben die zuletzt genannten Tabellen die Variablenwerte der vorhergehenden! Durch die Systemoption MSGLEVEL=I (info) wird in diesem Fall eine entsprechende Information im Log Fenster angezeigt. Im folgenden Beispiel: INFO: The variable x on data set WORK.EINS will be overwritten by data set WORK.ZWEI. INFO: The variable id on data set WORK.EINS will be overwritten by data set WORK.ZWEI. Standardeinstellung ist MSGLEVEL=N (note), wodurch keine Infos gegeben werden. ONE2ONE: DATA one2one; MERGE eins zwei; RUN; 8 ID B D B C X 4 5 2 3 Y 10 20 20 30 Z 40 50 . . Über die Systemoption MERGENOBY=WARN|ERROR erscheint im Log eine Warnung bzw. Fehlermeldung, wenn MERGE ohne BY Anweisung verwendet wird. Standardeinstellung ist MERGENOBY=NOWARN. SAS Programmierung für Fortgeschrittene I Stürzl Januar 08/SASFRT1.DOC Seite 37 von 59 DATA STEP Programmierung 5. Verknüpfung von Tabellen (SET, MERGE) 5.2.1 Optionen der MERGE Anweisung END=variable Mit Hilfe der END Option der MERGE Anweisung lässt sich eine temporäre Variable erzeugen, die anzeigt, ob die letzte Beobachtung der genannten Tabellen gelesen wird (Wert=1) oder nicht (Wert=0). DATA neu; MERGE eins zwei END=letzter; BY id; RUN; MERGEBY ID X Y Z letzter A B B C D 1 4 2 3 5 10 20 20 30 . . 40 40 . 50 0 0 0 0 1 (IN=variable) Beim Merge mit By-Gruppen (Match Merge) lässt sich mit Hilfe der IN= Tabellenoption eine temporäre Variable erzeugen, die anzeigt, ob die jeweilige Tabelle mindestens eine Beobachtung zu der jeweiligen By-Gruppe beigetragen hat (Wert=1) oder nicht (Wert=0). DATA mergeby1; MERGE eins (IN=ex1) zwei (IN=ex2); BY id; RUN; MERGEBY1 ID X Y Z ex1 ex2 A B B C D 1 4 2 3 5 10 20 20 30 . . 40 40 . 50 1 1 1 1 0 0 1 1 0 1 ACHTUNG: Diese Bedeutung unterscheidet sich von der IN= Tabellenoption in der SET Anweisung! Ob eine Beobachtung tatsächlich aus der entsprechenden Tabelle stammt, wird beim Merge mit By-Gruppen von der IN= Variable standardmäßig nur dann richtig angezeigt, wenn eine 1:1 Verknüpfung vorliegt, d.h. wenn in jeder Tabelle jede By-Gruppe jeweils höchstens einmal vorkommt. Sobald in einer Tabelle eine By-Gruppe mehrfach vorkommt (1:n) oder in mehr als einer Tabelle dieselbe By-Gruppe mehrfach vorkommt (m:n) zeigt die IN= Variable die Herkunft der Beobachtung bei allen Wiederholungen falsch an! Das liegt daran, dass die IN= Variablen innerhalb der By-Gruppen ein automatisches Retain erhalten. Dies kann dadurch verhindert werden, indem man die verwendeten IN= Variablen vor der Merge Anweisung mit Missing Value initialisiert. DATA mergeby2; ex1=.; * Autoretain verhindern; ex2=.; * Autoretain verhindern; MERGE eins (IN=ex1) zwei (IN=ex2); BY id; RUN; SAS Programmierung für Fortgeschrittene I Stürzl Januar 08/SASFRT1.DOC MERGEBY2 ex1 ex2 ID X Y Z 1 1 1 1 0 0 1 . 0 1 A B B C D 1 4 2 3 5 10 20 20 30 . . 40 40 . 50 Seite 38 von 59 DATA STEP Programmierung 5. Verknüpfung von Tabellen (SET, MERGE) Übung51: X: A 100 Y: B 1 2 3 4 5 Wie sind die Tabellen X und Y zu verknüpfen, damit folgende Tabellen entstehen? XY1: B 100 1 2 3 4 5 XY2: A 100 B 1 XY3: A 100 B 3 XY4: A 100 100 100 100 100 B 1 2 3 4 5 Übung52: Optional Berechnen Sie für jede Datei in "DIRLIST" (siehe Übung41 auf Seite 26) den prozentualen Anteil der Dateigröße im Dateiverzeichnis. SAS Programmierung für Fortgeschrittene I Stürzl Januar 08/SASFRT1.DOC Seite 39 von 59 DATA STEP Programmierung 5. Verknüpfung von Tabellen (SET, MERGE) 5.3. By-Gruppen Verarbeitung (by-processing) mit SET und MERGE Mit Hilfe der BY Anweisung lassen sich Daten gruppenweise verarbeiten (by-processing). Dies ist sowohl bei Prozeduren als auch im Data Step möglich, wobei immer vorausgesetzt wird, dass die Daten bereits entsprechend sortiert sind. Syntax: BY variable1 <variable2 ...>; Im Data Step kann die BY Anweisung ausschließlich in Verbindung mit den Anweisungen SET, MERGE oder UPDATE verwendet werden. In diesem Fall werden für jede By-Variable die temporären Variablen FIRST.variable und LAST.variable angelegt, die ausschließlich den Wert 0 oder 1 enthalten (Boolesche Variablen). Dadurch lässt sich erkennen, ob eine By-Variable ihre Ausprägung wechselt. Regel: FIRST.variable ist genau dann 1, wenn eine bestimmte Ausprägung von variable zum erstenmal auftritt, sonst 0 LAST.variable ist genau dann 1, wenn eine bestimmte Ausprägung von variable zum letztenmal auftritt, sonst 0 Falls mehrere By-Variablen zusammen verwendet werden, ist die Ausprägung von variable innerhalb aller vorangegangen By-Variablen maßgeblich. Beispiel 34: Interleaving DATA setby; SET eins zwei; BY id; RUN; SETBY ID X Y Z A 1 10 . 1 1 B B B 2 2 4 20 20 . . . 40 1 0 0 0 0 1 C 3 30 . 1 1 D 5 . 50 1 1 MERGEBY: ID X Y Z A 1 10 . 1 1 B B 4 2 20 20 40 40 1 0 0 1 C 3 30 . 1 1 D 5 . 50 1 1 FIRST.id LAST.id Beispiel 35: Match Merging DATA mergeby; MERGE eins zwei; BY id; RUN; SAS Programmierung für Fortgeschrittene I Stürzl Januar 08/SASFRT1.DOC FIRST.id LAST.id Seite 40 von 59 DATA STEP Programmierung 5. Verknüpfung von Tabellen (SET, MERGE) Beispiel 36: Fortlaufende Nummerierung der Beobachtungen innerhalb von By-Gruppen z.B. Männer und Frauen jeweils bei 1 beginnend fortlaufend nummerieren PROC SORT DATA=kino; BY sex name; RUN; DATA kino2; SET kino; BY sex; IF FIRST.sex THEN nr=0; nr+1; RUN; Ö NAME SEX Benno Dustin Gérard Götz Franka Marlene Fürmann Hoffmann Depardieu George Potente Dietrich 1 1 1 1 2 2 NR 1 2 3 4 1 2 Übung53: Die folgende Tabelle ist nach Land und Stadt sortiert (by land stadt;). Welche Ausprägungen haben die First.- und Last.Variablen? Land Stadt Australien Australien Deutschland Deutschland Deutschland Schweiz Canberra Sydney Berlin Berlin Freiburg Freiburg FIRST.land LAST.land FIRST.stadt LAST.stadt Übung54: Berechnen Sie auf der Grundlage der Daten der Excel Tabelle MESSTAB1.XLS für jede Messung den zeitlichen Abstand in Tagen zur jeweils ersten Messung der ID (siehe Übung42 auf Seite 30). SAS Programmierung für Fortgeschrittene I Stürzl Januar 08/SASFRT1.DOC Seite 41 von 59 DATA STEP Programmierung 5. Verknüpfung von Tabellen (SET, MERGE) Übung55: Dublettencheck In der Tabelle BWAHL2 sind die amtlichen Endergebnisse der Bundestagswahlen von 2002 und 1998 auf Wahlkreisebene enthalten. Für jeden der 299 Wahlkreise sind pro Wahljahr getrennt für die Erst- und Zweitstimmen neben der Anzahl der Wahlberechtigten für SPD, CDU, CSU, GRÜNE, FDP und PDS die Anzahl der jeweils abgegebenen gültigen Stimmen enthalten. Zu Übungszwecken ist die Tabelle BWAHL2 so verändert, dass zu manchen Wahlkreisen mehrere Ergebnisse pro Jahr und Stimme vorliegen (Dubletten). Erstellen Sie eine Liste aller vorhandenen Dubletten und vergleichen Sie deren Ergebnisse untereinander. Hinweis: Die Tabelle BWAHL2 hat folgende Variablen: # Variable Type Len Format Label ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ 1 Wkreis Char 65 Wahlkreis 2 Land Char 30 Bundesland 3 Jahr Char 4 Wahljahr 4 Stimme Num 8 Stimme 5 Wberecht Num 8 COMMAX10. Wahl- berechtigte 6 Gueltig Num 8 COMMAX10. Gültige Stimmen 7 SPD Num 8 COMMAX. SPD 8 CDU Num 8 COMMAX. CDU 9 CSU Num 8 COMMAX. CSU 10 Gruene Num 8 COMMAX. GRÜNE 11 FDP Num 8 COMMAX. FDP 12 PDS Num 8 COMMAX. PDS Quelle: Destatis, Statistisches Bundesamt, Bundeswahlleiter (www.bundeswahlleiter.de) Übung56: Dubletten löschen Löschen Sie alle unplausiblen Dubletten. SAS Programmierung für Fortgeschrittene I Stürzl Januar 08/SASFRT1.DOC Seite 42 von 59 DATA STEP Programmierung 6. Arrays 6. Arrays Mit Hilfe der ARRAY Anweisung (Deklarationsanweisung) lassen sich Variablen zu einem Feld (array) zusammenfassen. Falls sie noch nicht existieren, werden sie dadurch definiert. Der Feldname muss ein gültiger SAS Name sein, der nicht als Variable oder Funktion vorkommt. Jede Variable entspricht genau einem Element des Feldes und kann sowohl über den Variablennamen als auch über den Arraynamen und einen Index angesprochen werden. Der Variablentyp innerhalb eines Arrays muss einheitlich sein (numerisches oder character Array). Mehrdimensionale Arrays sind möglich. Array Verarbeitung bietet sich an, wenn dieselben Aktionen mit verschiedenen Variablen durchgeführt werden sollen. Sie verkürzt den Programmcode und macht ihn übersichtlicher. Beispiele für eindimensionale Arrays: ARRAY x [3]; fasst die Variablen x1, x2, x3 zu einem Array "x" zusammen. Sie können dadurch zusätzlich auch als x[1], x[2], x[3] angesprochen werden. Falls die Variablen noch nicht existieren, werden sie dadurch definiert (num.). ARRAY x [3] _TEMPORARY_; dito, x1-x3 nur temporäre Variablen mit automatischem Retain ARRAY x [3] $; umfasst die alphanumerischen Variablen x1, x2, x3 ARRAY x [3] $4.; umfasst die alphanumerischen Variablen x1, x2, x3 mit der Länge 4 Byte ARRAY x [3] (0 0 1); x1=0, x2=0, x3=1 ARRAY x [3] a b c; umfasst die Variablen a, b, c, sie lassen sich auch als x[1], x[2], x[3] ansprechen ARRAY x [*] a b c; dito, die Anzahl der Elemente wird automatisch erkannt ARRAY x [0:2] a b c; umfasst die Variablen a, b, c, sie lassen sich auch als x[0], x[1], x[2] ansprechen ARRAY x [*] a:; umfasst alle Variablen, deren Name mit "a" beginnt ARRAY x [*] a1-a12; umfasst alle Variablen a1, a2, ..., a12 ARRAY x [*] a--z; umfasst alle Variablen a bis z in der Reihenfolge wie sie in der Tabelle vorliegen ARRAY x [*] _NUMERIC_; umfasst alle numerischen Variablen ARRAY x [*] _CHARACTER_; umfasst alle alphanumerischen Variablen Beispiele für zweidimensionale Arrays: x[1,1]=x1 x[2,1]=x3 x[3,1]=x5 ARRAY x [3,2]; ARRAY x [3,2] a b c d x[1,2]=x2 x[2,2]=x4 x[3,2]=x6 e f; SAS Programmierung für Fortgeschrittene I Stürzl Januar 08/SASFRT1.DOC Seite 43 von 59 DATA STEP Programmierung 6. Arrays Beispiele für den Umgang mit Array Elementen : ARRAY x [10]; x[1]=100; x[3]=x[1] + x[2]; DO i=1 TO DIM(x); * Funktion DIM liefert Anzahl der Array-Elemente; x[i]=.; END; PUT x[*]=; * schreibt alle Array-Elemente mit Variablenname in eine Zeile in den Log; PUT (x[*]) (BEST.); * schreibt alle Array-Elemente formatiert in den Log; PUT (x[*]) (+(-1) ";"); * schreibt alle Array-Elemente durch Semikolon getrennt in den Log; mittel=MEAN(OF x[*]); IF NMISS(OF x[*]) > 0 THEN ...; Beispiel 37: Eins-mal-eins DATA einsmal1; ARRAY reihe [12]; DO i=1 TO DIM(reihe); DO j=1 TO DIM(reihe); reihe[j]=i*j; END; OUTPUT; * eine Reihe als Beobachtung schreiben; END; RUN; 1 2 3 4 5 6 7 8 9 10 11 12 2 4 6 8 10 12 14 16 18 20 22 24 3 6 9 12 15 18 21 24 27 30 33 36 4 8 12 16 20 24 28 32 36 40 44 48 5 10 15 20 25 30 35 40 45 50 55 60 6 12 18 24 30 36 42 48 54 60 66 72 SAS Programmierung für Fortgeschrittene I Stürzl Januar 08/SASFRT1.DOC 7 14 21 28 35 42 49 56 63 70 77 84 8 16 24 32 40 48 56 64 72 80 88 96 9 18 27 36 45 54 63 72 81 90 99 108 10 20 30 40 50 60 70 80 90 100 110 120 11 22 33 44 55 66 77 88 99 110 121 132 12 24 36 48 60 72 84 96 108 120 132 144 Seite 44 von 59 DATA STEP Programmierung 6. Arrays Übung61: Formel für die Varianz Definieren Sie folgendes Array x 1 2 3 4 ... 9 10 Berechnen Sie damit für alle x die Summe der quadratischen Abweichungen von ihrem Mittelwert (corrected sum of squares) nach css = n ∑( x i =1 i − x )2 SAS Programmierung für Fortgeschrittene I Stürzl Januar 08/SASFRT1.DOC Seite 45 von 59 DATA STEP Programmierung 7. Vertikalisierung und Horizontalisierung von SAS Tabellen 7. Vertikalisierung und Horizontalisierung von SAS Tabellen Für die Auswertung mit SAS ist es oft entscheidend, in welcher Struktur die Daten vorliegen. Befinden sich die zu verarbeitenden Datenwerte in der SAS Tabelle (data set) "untereinander", d.h. in derselben Variable auf verschiedene Beobachtungen (Observations) verteilt oder "nebeneinander" in derselben Beobachtung in verschiedenen Variablen? Je nach Art der Auswertung kann die eine oder die andere Struktur günstiger sein. Viele Prozeduren (PROC MEANS, UNIVARIATE, TTEST, ...) setzen voraus, dass die zu verarbeitenden Datenwerte in einer Variable enthalten sind, die Tabelle also vertikal strukturiert ist. Für andere Prozeduren (PROC FREQ, TABULATE, CORR, REG, ...) und vergleichende Untersuchungen im Datenschritt (Data Step) ist es notwendig, dass die zu vergleichenden Daten sich in einer Beobachtung befinden, die Tabelle also horizontal strukturiert ist. Datentechnisch betrachtet handelt es sich bei der Umwandlung von einer Struktur in die andere um ein geeignetes Vertauschen von Variablen und Beobachtungen. Was vorher in verschiedenen Beobachtungen steht, soll später in verschiedenen Variablen abgelegt werden und umgekehrt. Die Tabelle wird in bestimmten Teilen "gekippt" oder transponiert. Im folgenden werden verschiedene Möglichkeiten dieser Transformation vorgestellt. Der automatisierten Methode mit der Prozedur TRANSPOSE werden verschiedene Lösungen im Datenschritt gegenübergestellt. Die Verwendung von PROC TRANSPOSE ist meist einfacher zu realisieren, bietet dafür jedoch weniger Einfluss- und Gestaltungsmöglichkeiten. Maximale Flexibilität bei der Erstellung der neuen Struktur bietet die Transformation im Datenschritt. Begriffe: • Messwert-Variable enthält die zu untersuchenden Datenwerte, die transponiert werden. • Schlüsselvariable (ID-Variable, Class-Variable) enthält identifizierende Merkmale (Schlüssel) und trägt zur Klassifizierung einer Beobachtung bei. • In der Vertikalen Datenstruktur im engeren Sinn (1. Normalform) gibt es genau eine Messwert-Variable und eine beliebige Anzahl von Schlüsselvariablen, die klassifizieren, um welchen Messwert es sich handelt. Jede Kombination von Ausprägungen der Schlüsselvariablen (Schlüssel) sollte nur einmal vorkommen, d.h. eindeutig sein. Die vertikale Struktur zeichnet sich dadurch aus, dass weitere Daten sehr leicht eingefügt werden können und über By-Gruppen sehr einfach verarbeitet werden können. • Die Horizontale Datenstruktur im engeren Sinn würde nur aus einer Beobachtung mit vielen MesswertVariablen bestehen, hat jedoch wenig praktische Bedeutung. Die meisten Tabellen liegen in einer Mischform mit mehreren Messwert und Schlüsselvariablen vor. Zu einer oder mehreren Schlüsselvariablen sind verschiedene Messwert-Variablen horizontal nebeneinander angeordnet. Dadurch stehen alle zu einer Kombination von Schlüsseln vorhanden Messwerte übersichtlich nebeneinander und lassen sich gut vergleichen. Bei den Transformationen handelt es sich darum, eine Tabelle "vertikaler" oder "horizontaler" zu machen, das heißt Schlüsselvariablen hinzuzufügen und neue Beobachtungen zu bilden (= Vertikalisierung) oder Schlüsselvariablen aufzulösen und neue Variablen zu bilden (= Horizontalisierung). SAS Programmierung für Fortgeschrittene I Stürzl Januar 08/SASFRT1.DOC Seite 46 von 59 DATA STEP Programmierung 7. Vertikalisierung und Horizontalisierung von SAS Tabellen Beispiel: Fiktive Messwerte von Herzfrequenz und Körpertemperatur verschiedener Patienten zu verschiedenen Zeitpunkten. 1. Vertikale Struktur mit einer Messwert-Variable (1. Normalform) und drei Schlüsselvariablen (pro Messwert eine Beobachtung) s3 ID1 patient A A A A A A B B B B B B ID2 zeit 1 1 2 2 3 3 1 1 2 2 3 3 ID3 param Puls Temp Puls Temp Puls Temp Puls Temp Puls Temp Puls Temp MESS mess 72 36,3 85 36,7 110 37,2 80 38,1 120 38,6 . 39,0 ← Diese Beobachtung könnte auch fehlen 2. Struktur mit zwei Messwertvariablen und zwei Schlüsselvariablen (alle Messwerte zu einem Patienten und einem Zeitpunkt in einer Beobachtung) s2 ID1 patient A A A B B B ID2 zeit 1 2 3 1 2 3 MESS1 puls 72 85 110 80 120 . MESS2 temp 36,3 36,7 37,2 38,1 38,6 39,0 3. Struktur mit einer Schlüsselvariable (alle Messwerte zu einem Patienten in einer Beobachtung) s1 ID1 patient A B MESS11 puls_t1 72 80 MESS12 puls_t2 85 120 MESS13 puls_t3 110 . SAS Programmierung für Fortgeschrittene I Stürzl Januar 08/SASFRT1.DOC MESS21 temp_t1 36,3 38,1 MESS22 temp_t2 36,7 38,6 MESS23 temp_t3 37,2 39,0 Seite 47 von 59 DATA STEP Programmierung 7. Vertikalisierung und Horizontalisierung von SAS Tabellen 7.1. Vertikalisierung Hier handelt es sich um den Übergang von der höherwertigen zu einer einfacheren Struktur, was vergleichsweise leicht zu erreichen ist. Informationen, die auf verschiedene Variablen verteilt in einer Beobachtung stehen, sollen auf mehrere Beobachtungen aufgeteilt werden. Dabei werden Schlüsselvariablen hinzugefügt und neue Beobachtungen gebildet, sowie bestehende Messwertvariablen aufgelöst. Beispiel 38: Transformation Tabelle s2 → s3, d.h. Puls- und Temperaturmesswerte in verschiedene Beobachtungen aufteilen (Schlüsselvariable "Param" einführen) Lösung mit PROC TRANSPOSE PROC SORT DATA=s2; BY patient zeit; RUN; PROC TRANSPOSE DATA=s2 OUT=s3; VAR puls temp; BY patient zeit; RUN; ⇒ OBS PATIENT 1 2 3 4 5 6 7 8 9 10 11 12 9 ZEIT A A A A A A B B B B B B 1 1 2 2 3 3 1 1 2 2 3 3 _NAME_9 puls temp puls temp puls temp puls temp puls temp puls temp COL1 72.0 36.3 85.0 36.7 110.0 37.2 80.0 38.1 120.0 38.6 . 39.0 Die automatisch erzeugte Variable _NAME_ enthält die Namen der transponierten Variablen der VAR Anweisung. Die genaue Ausprägung richtet sich nach der SAS Version und ab Version 8 auch nach der Systemoption VALIDVARNAME. SAS Version VALIDVARNAME Ausprägung von _NAME_ 6.12 - in Großbuchstaben (max. 8 Zeichen) ab 8.0 V7 (Standard) wie definiert (max. 32 Zeichen) UPCASE in Großbuchstaben (max. 32 Zeichen) V6 in Großbuchstaben (max. 8 Zeichen) Falls eine der transponierten Variablen der VAR Anweisung ein Label besitzt, wird zusätzlich die Variable _LABEL_ erzeugt, welche das ursprüngliche Label enthält. SAS Programmierung für Fortgeschrittene I Stürzl Januar 08/SASFRT1.DOC Seite 48 von 59 DATA STEP Programmierung 7. Vertikalisierung und Horizontalisierung von SAS Tabellen DATENSCHRITT Lösung mit OUTPUT DATA s3; SET s2; param="Puls"; mess=puls; OUTPUT; param="Temp"; mess=temp; OUTPUT; DROP puls temp; RUN; ⇒ OBS 1 2 3 4 5 6 7 8 9 10 11 12 PATIENT A A A A A A B B B B B B ZEIT 1 1 2 2 3 3 1 1 2 2 3 3 PARAM Puls Temp Puls Temp Puls Temp Puls Temp Puls Temp Puls Temp MESS 72.0 36.3 85.0 36.7 110.0 37.2 80.0 38.1 120.0 38.6 . 39.0 Im Gegensatz zur Lösung mit PROC TRANSPOSE bietet die Datenschritt Lösung mehr Möglichkeiten bei der Gestaltung der neuen Schlüsselvariable und ihrer Ausprägungen. Übung71: Transformation Tabelle s1 → s2 (Messwerte von verschiedenen Zeitpunkten in unterschiedliche Beobachtungen bringen, Schlüsselvariable „Zeit“ bilden, auf zwei Messwert-Variablen „Puls“ und „Temp“ reduzieren) Verwenden Sie dazu die Programmdatei UEBUNG71.SAS als Vorlage und lösen Sie die Aufgabe zunächst mit einem Datenschritt und anschließend auch mit PROC TRANSPOSE. Übung72: Wie lassen sich die Daten der Excel Tabelle "MESSTAB1.XLS" (siehe Übung42 auf Seite 30) in eine vertikal strukturierte SAS Tabelle mit nur einer Messwert-Variablen pro ID und Messdatum transformieren? SAS Programmierung für Fortgeschrittene I Stürzl Januar 08/SASFRT1.DOC Seite 49 von 59 DATA STEP Programmierung 7. Vertikalisierung und Horizontalisierung von SAS Tabellen 7.2. Horizontalisierung Die Horizontalisierung einer Tabelle stellt den Übergang von einer einfachen zu einer höherwertigen Struktur dar und gestaltet sich naturgemäß aufwendiger. Informationen, die über viele Beobachtungen verteilt sind sollen in einer Beobachtung zusammengefasst werden. Dabei werden Schlüsselvariablen und damit Beobachtungen aufgelöst und neue Messwertvariablen gebildet. Beispiel 39: Transformation Tabelle s3 → s2, d.h. Puls- und Temperaturmesswerte eines Patienten zu einem Messzeitpunkt in eine Beobachtung bringen (Schlüsselvariable "Param" auflösen) Lösung mit PROC TRANSPOSE PROC SORT DATA=s3; BY patient zeit; RUN; PROC TRANSPOSE DATA=s3 OUT=s2; VAR mess; BY patient zeit; ID param; RUN; ⇒ OBS 1 2 3 4 5 6 PATIENT A A A B B B ZEIT 1 2 3 1 2 3 _NAME_ MESS MESS MESS MESS MESS MESS Puls Temp 72 85 110 80 120 . 36.3 36.7 37.2 38.1 38.6 39.0 ACHTUNG: Die ID Anweisung sollte bei der Horizontalisierung immer verwendet werden. Hier wird die aufzulösende Schlüsselvariable (hier "param") angegeben. Ihre Ausprägungen werden automatisch für die Bildung der neuen Variablen verwendet. Sie müssen deshalb die SAS Namenskonvention erfüllen. Ohne die ID Anweisung werden die Beobachtungen in der vorliegenden Reihenfolge transponiert. Bei unsortierten Daten oder bei fehlenden Schlüsselkombinationen in der vertikalen Struktur kann es dabei zu falschen Zuordnungen der Werte zu den neuen Variablen in der horizontalen Struktur kommen! Beispiel für unkontrollierte und FALSCHE Horizontalisierung ohne ID Anweisung: PROC TRANSPOSE DATA=s3 OUT=s2; WHERE mess^=.; Zur Simulation einer uneinheitlichen Datenstruktur VAR mess; BY patient zeit; RUN; ⇒FALSCH! OBS ... 6 PATIENT B ZEIT 3 _NAME_ Puls MESS 39.0 SAS Programmierung für Fortgeschrittene I Stürzl Januar 08/SASFRT1.DOC Temp . Seite 50 von 59 DATA STEP Programmierung 7. Vertikalisierung und Horizontalisierung von SAS Tabellen DATENSCHRITT (DATA STEP) Lösungen Hier gibt es viele Möglichkeiten, die mehr oder weniger einfach sind. In allen Fällen kann der Transformationsprozess genau gesteuert werden. Die Namen aller neu zu erstellenden Variablen lassen sich genau vorgeben. Außerdem stehen in demselben Datenschritt die neu erstellten Variablen zur Weiterverarbeitung zur Verfügung (angedeutet durch "*...;"). Alle hier beschriebenen Methoden arbeiten mit wiederholt angewendeten SET Anweisungen, wobei jedes Mal eine neue Beobachtung aus der vertikalen Tabelle gelesen wird. Entscheidend ist dabei, dass die Beobachtung der neu zu erstellenden Tabelle erst dann beendet d.h. weggeschrieben wird, wenn alle Beobachtungen, die zusammengefasst werden sollen, aus der vertikalen Tabelle gelesen sind. Das heißt, es werden mehr Beobachtungen gelesen als geschrieben. Datenschrittlösung 1 mit RETAIN und OUTPUT Arbeitsweise: Es werden alle Beobachtungen der vertikalen Tabelle gelesen und der Messwert jeweils in die entsprechende neu zu erstellende Variable (hier "puls" oder "temp") geschrieben. Durch die Retain Anweisung wird die Ausprägung zur nächsten Beobachtung durchgereicht. Schließlich werden nur die Beobachtungen am Ende jeder By-Gruppe geschrieben. Alle übrigen Beobachtung bleiben nicht erhalten. PROC SORT DATA=s3; BY patient zeit; RUN; DATA s2; RETAIN puls temp; * neu zu bildende Messwertvariablen; SET s3; BY patient zeit; IF param="Puls" THEN puls=mess; IF param="Temp" THEN temp=mess; *...; IF LAST.zeit THEN OUTPUT; DROP param mess; RUN; ⇒ OBS PULS TEMP PATIENT 1 2 3 4 5 6 72 85 110 80 120 . 36.3 36.7 37.2 38.1 38.6 39.0 A A A B B B SAS Programmierung für Fortgeschrittene I Stürzl Januar 08/SASFRT1.DOC ZEIT 1 2 3 1 2 3 Seite 51 von 59 DATA STEP Programmierung 7. Vertikalisierung und Horizontalisierung von SAS Tabellen ACHTUNG: Bei dieser Methode kann es auch zu falschen Zuordnungen kommen, wenn Schlüsselkombinationen in der vertikalen Struktur fehlen. z. B. Beobachtung fehlt für den Parameter Puls bei Patient B zum Zeitpunkt 3. DATA s2; RETAIN puls temp; SET s3; BY patient zeit; WHERE mess^=.; Zur Simulation einer uneinheitlichen Datenstruktur IF param="Puls" THEN puls=mess; IF param="Temp" THEN temp=mess; *...; IF LAST.zeit THEN OUTPUT; DROP param mess; RUN; ⇒FALSCH! OBS ... 6 PULS TEMP PATIENT 120 39.0 B ZEIT 3 Dies kann verhindert werden, indem die neu zu bildenden Messwertvariablen zu Beginn jeder neuen By-Gruppe mit missing value initialisiert werden. ... IF FIRST.zeit THEN DO; puls=.; temp=.; END; IF param="Puls" THEN puls=mess; IF param="Temp" THEN temp=mess; ... SAS Programmierung für Fortgeschrittene I Stürzl Januar 08/SASFRT1.DOC Seite 52 von 59 DATA STEP Programmierung 7. Vertikalisierung und Horizontalisierung von SAS Tabellen Datenschrittlösung 2 mit DO-UNTIL Schleife Arbeitsweise: Innerhalb jeder By-Gruppe wird zwar mehrmals aus der vertikalen Tabelle gelesen, jedoch nur auf einer einzigen Beobachtung gearbeitet. Deshalb kann die RETAIN und OUTPUT Anweisung entfallen. Im Gegensatz zur vorherigen Lösung gibt es auch bei fehlenden Schlüsselkombinationen keine falschen Zuordnungen, da bei jedem Wechsel der By-Gruppe alle Variablen mit fehlenden Werten (missing values) neu initialisiert werden. Fehlende Schlüsselkombinationen in der vertikalen Struktur werden also korrekt durch fehlende Werte in der horizontalen Struktur dargestellt. PROC SORT DATA=s3; BY patient zeit; RUN; DATA s2; DO UNTIL (LAST.zeit); SET s3; BY patient zeit; IF param="Puls" THEN puls=mess; IF param="Temp" THEN temp=mess; nr=_N_; END; *...; DROP param mess; RUN; ⇒ OBS 1 2 3 4 5 6 PATIENT A A A B B B ZEIT 1 2 3 1 2 3 PULS TEMP NR 72 85 110 80 120 . 36.3 36.7 37.2 38.1 38.6 39.0 1 2 3 4 5 6 SAS Programmierung für Fortgeschrittene I Stürzl Januar 08/SASFRT1.DOC Seite 53 von 59 DATA STEP Programmierung 7. Vertikalisierung und Horizontalisierung von SAS Tabellen Datenschrittlösung 3 mit DO-UNTIL Schleife, Arrays und Formaten Arbeitsweise: Wie vorherige Lösung, jedoch werden statt IF-Abfragen Arrays und gegebenenfalls Formate verwendet. Eignet sich besonders, wenn viele Variablen neu gebildet werden sollen und damit die Liste der Abfragen sehr lang werden würde. (effizientere Programmierung). Diese Methode ist auch für komplexe Transformationen verwendbar, wenn mehr als eine Schlüsselvariable aufgelöst werden soll (siehe Beispiel 40: Transformation Tabelle s3 → s1 auf Seite 55). Ziel der Formatierung ist es, die Ausprägungen der aufzulösenden Schlüsselvariablen in numerische Werte zu übersetzen (falls dies nicht schon der Fall ist), die sich als Indizes zur Steuerung von Arrays eignen. WICHTIG: Die numerische Reihenfolge im Format muss mit der Reihenfolge der Variablen im ARRAY übereinstimmen! (Die Ausprägung "Puls" wird durch das Format in den Wert "1" übersetzt und "Temp" in "2", entsprechend wird dann der ersten Variable im Array der Puls-Meßwert und der zweiten Variable der Temperatur-Messwert zugewiesen) PROC FORMAT; VALUE $ paramf "Puls"="1" "Temp"="2"; RUN; PROC SORT DATA=s3; BY patient zeit; RUN; DATA s2; ARRAY x [2] puls temp; DO UNTIL (LAST.zeit); SET s3; BY patient zeit; x[PUT(param,$paramf.)]=mess; END; *...; DROP param mess; RUN; SAS Programmierung für Fortgeschrittene I Stürzl Januar 08/SASFRT1.DOC Seite 54 von 59 DATA STEP Programmierung 7. Vertikalisierung und Horizontalisierung von SAS Tabellen Beispiel 40: Transformation Tabelle s3 → s1, d.h. alle Messwerte zu einem Patienten in eine Beobachtung bringen (Schlüsselvariablen "Param" und "Zeit" auflösen) Datenschrittlösung 3 PROC FORMAT; VALUE $ paramf "Puls"="1" "Temp"="2"; RUN; PROC SORT DATA=s3; BY patient; RUN; DATA s1; ARRAY x [2,3] puls_t1-puls_t3 temp_t1-temp_t3; DO UNTIL (LAST.patient); SET s3; BY patient; x[PUT(param,$paramf.), zeit]=mess; END; *...; DROP zeit param mess; RUN; ⇒ OBS PATIENT PULS_T1 PULS_T2 PULS_T3 1 2 A B 72 80 85 120 110 . SAS Programmierung für Fortgeschrittene I Stürzl Januar 08/SASFRT1.DOC TEMP_T1 TEMP_T2 TEMP_T3 36.3 38.1 36.7 38.6 37.2 39.0 Seite 55 von 59 DATA STEP Programmierung 7. Vertikalisierung und Horizontalisierung von SAS Tabellen Lösung mit PROC TRANSPOSE Die Prozedur TRANSPOSE kann bei der Horizontalisierung nur genau eine Schlüsselvariable auflösen (es wird nur eine Schlüsselvariable in der ID Anweisung akzeptiert). Wenn wie in diesem Fall zwei (oder mehr) Schlüsselvariablen aufgelöst werden sollen, so muss entweder die Prozedur zweimal (mehrmals) angewendet und die Ergebnistabellen anschließend verknüpft werden, oder es wird vorher eine neue Schlüsselvariable erstellt (hier "par_zeit"), die alle Kombinationen von Ausprägungen der bestehenden Schlüsselvariablen enthält. Diese Ausprägungen müssen jedoch die SAS Namenskonvention erfüllen, da sie für die Namen der neu zu erstellenden Variablen verwendet werden. DATA s3; LENGTH par_zeit $8; SET s3; par_zeit=COMPRESS(param||PUT(zeit, 1.)); RUN; PROC SORT DATA=s3; BY patient; RUN; PROC TRANSPOSE DATA=s3 OUT=s1; VAR mess; BY patient; ID par_zeit; RUN; ⇒ OBS PATIENT _NAME_ 1 2 A B mess mess Puls1 72 80 Temp1 Puls2 Temp2 36.3 38.1 85 120 36.7 38.6 SAS Programmierung für Fortgeschrittene I Stürzl Januar 08/SASFRT1.DOC Puls3 110 . Temp3 37.2 39.0 Seite 56 von 59 DATA STEP Programmierung 7. Vertikalisierung und Horizontalisierung von SAS Tabellen Beispiel 41: Transformation Tabelle s2 → s1, d.h. Alle Messwerte eines Patienten in eine Beobachtung bringen (Schlüsselvariable "Zeit" auflösen) Datenschrittlösung analog dem letzten Beispiel Lösung mit PROC TRANSPOSE Arbeitsweise: Transponieren der verschiedenen Messwert-Variablen in jeweils einem Prozedurschritt unter Verwendung der PREFIX Option zur Steuerung der zu erzeugenden Variablennamen. In Kombination mit der ID Anweisung beginnen alle Variablen dann mit derselben Zeichenfolge. Auch hier muss auf die Einhaltung der Namenskonvention geachtet werden. Die entstandenen Tabellen anschließend zusammenfassen. PROC SORT DATA=s2; BY patient; RUN; PROC TRANSPOSE DATA=s2 OUT=teil1 PREFIX=puls_; VAR puls; BY patient; ID zeit; RUN; ⇒ OBS PATIENT _NAME_ 1 2 A B puls puls puls_1 puls_2 puls_3 72 80 85 120 110 . PROC TRANSPOSE DATA=s2 OUT=teil2 PREFIX=temp_; VAR temp; BY patient; ID zeit; RUN; ⇒ OBS PATIENT _NAME_ 1 2 A B temp temp temp_1 temp_2 temp_3 36.3 38.1 36.7 38.6 37.2 39.0 DATA s1; MERGE teil1 teil2; BY patient; DROP _name_; RUN; SAS Programmierung für Fortgeschrittene I Stürzl Januar 08/SASFRT1.DOC Seite 57 von 59 DATA STEP Programmierung 7. Vertikalisierung und Horizontalisierung von SAS Tabellen Übung73: Wie können die in Übung72 vertikal strukturierten Daten wieder in die ursprüngliche (horizontale) Form der Excel Tabelle "MESSTAB1.XLS" gebracht werden (Schlüsselvariablen "Parameter" und "Gerät" auflösen)? SAS Programmierung für Fortgeschrittene I Stürzl Januar 08/SASFRT1.DOC Seite 58 von 59 DATA STEP Programmierung 8. Dictionary Tables 8. Dictionary Tables Das SAS System stellt in den Dictionary Tables mächtige Meta-Informationen über SAS Bibliotheken, SAS Dateien, externe Dateien, System Optionen und Makro Variablen zur Verfügung, welche auch in vielen SAS Fenstern zu sehen sind (z.B. Libname, Dir, Catalog, Filename Fenster). Dictionary Tables sind spezielle schreibgeschützte SQL Objekte (read-only) der Bibliothek DICTIONARY, welche vom SAS System laufend aktualisiert werden und jeweils den aktuellen Zustand des Systems wiedergeben. Sie können ausschließlich mit PROC SQL gelesen werden. Übersicht über die Dictionary Tables: Table DICTIONARY.CATALOGS Beschreibung DICTIONARY.COLUMNS Enthält sämtliche Variablen (Columns) aller SAS Tabellen (data sets) und Views aus allen definierten Bibliotheken DICTIONARY.EXTFILES Enthält alle definierten Filerefs und benutzten Programmdateien DICTIONARY.INDEXES Enthält alle definierten Indices aller SAS Tabellen (data sets) DICTIONARY.MACROS Enthält alle definierten Makrovariablen und zeigt neben dem Namen und aktuellen Wert auch den Namen der Systemtabelle (scope) DICTIONARY.MEMBERS Enthält alle SAS Dateien (data sets, catalogs, views, etc.) aus allen definierten Bibliotheken DICTIONARY.OPTIONS Enthält die aktuelle Setzung aller Systemoptionen DICTIONARY.STYLES Enthält alle verfügbaren Styles DICTIONARY.TABLES Enthält alle SAS Tabellen (data sets) und Views aus allen definierten Bibliotheken, jedoch mit mehr Informationen als DICTIONARY.MEMBERS DICTIONARY.TITLES Enthält alle aktuellen Titel- und Fußzeilen DICTIONARY.VIEWS Enthält alle Views aus allen definierten Bibliotheken Enthält alle Katalogeinträge aus allen Katalogen aller definierten Bibliotheken PROC SQL ist eine interaktive Prozedur, d.h. es können beliebig viele SQL Anweisungen (statements) nacheinander ausgeführt werden. Die Prozedur wird erst durch die Anweisung QUIT, einen Datenschritt oder einen neuen Prozedurschritt beendet. Im Gegensatz zur üblichen SAS Notation werden Variablen durch Kommas anstatt durch Blanks getrennt. Bei der Verwendung der Dictionary Tables ist zu beachten: • Datenwerte von Charactervariablen enthalten meistens Großbuchstaben • Data Set Optionen können nicht verwendet werden Einstieg in die Online Hilfe über das Kommando "help dictionary tables" SAS Help and Documentation Î SAS Products Î Base SAS Î SAS SQL Procedures User’s Guide Î Programming with the SQL Procedure Î Accessing SAS System Information Using DICTIONARY Tables SAS Programmierung für Fortgeschrittene I Stürzl Januar 08/SASFRT1.DOC Seite 59 von 59 SAS Hilfe SAS Help and Documentation Version 9 SAS Hilfe SAS Hilfe 1 1. SAS Help and Documentation Version 9 2 1.1. SAS OnlineDoc 9.1 for the Web 3 2. OnlineDoc Version 8 4 3. Online Hilfe Version 8 6 4. SAS Links 7 5. SAS Diskussionsforen 11 5.1. SAS-L 11 5.2. Redscope 13 5.3. User Forums von SAS Institute 14 5.4. SAS-EDU 14 5.5. Deutsches SAS-Forum 14 6. SAS Institute Listserver 15 7. Übung: SAS Hilfe 16 SAS Hilfe, Stürzl, Januar 08/Sashilfe.doc 1 SAS Hilfe SAS Help and Documentation Version 9 1. SAS Help and Documentation Version 9 Umfasst Online Hilfe und OnlineDoc für die lizenzierte Software. Wird mit SAS installiert und von dort gestartet. • Help → SAS Help and Documentation oder • Cursor auf SAS Keyword stellen + F1 drücken SAS Hilfe, Stürzl, Januar 08/Sashilfe.doc 2 SAS Hilfe 1.1. SAS Help and Documentation Version 9 SAS OnlineDoc 9.1 for the Web Übersicht: http://support.sas.com/v9doc OnlineDoc 9.1 PDF (buchweise): http://support.sas.com/documentation/onlinedoc/91pdf OnlineDoc 9.1.3 im HTML Format: http://support.sas.com/onlinedoc/913 Ist im Vergleich zu SAS Help and Documentation etwas anders strukturiert. SAS Hilfe, Stürzl, Januar 08/Sashilfe.doc 3 SAS Hilfe OnlineDoc Version 8 2. OnlineDoc Version 8 Die SAS OnlineDoc® enthält den vollständigen Inhalt der Reference Handbücher im HTML Format und setzt einen java-fähigen Browser voraus (Internet Explorer 5.0 "strongly recomended"). Die SAS OnlineDoc Version 8 (Februar 2000) ist unabhängig vom SAS System installiert und gilt auch für die SAS Version 8.1 und 8.2. Neuerungen, die erst nach Version 8.0 eingeführt wurden sind darin jedoch noch nicht enthalten. Diese sind ausschließlich in der Online Hilfe zu finden. Der Aufruf kann von der CD oder einer Festplatte erfolgen, auf der die CD installiert wurde. z.B. C:\SASOnlineDocV8\sasdoc\sashtml\onldoc.htm oder via Internet http://v8doc.sas.com Innerhalb des SAS Systems kann die OnlineDoc aufgerufen werden über das Help Menü Help Î Books and Training Î SAS OnlineDoc Favoriten (Bookmarks) Besonders hilfreiche Seiten der OnlineDoc können auch als Favoriten (Bookmarks) gespeichert werden. Beim direkten Aufruf einer Seite erscheint dann die Seite ohne den Navigationsframe. SAS Hilfe, Stürzl, Januar 08/Sashilfe.doc 4 SAS Hilfe OnlineDoc Version 8 Suchfunktion (Search Lasche) • Search in.... ermöglicht die Einschränkung der durchsuchten Quellen. Standard ist die gesamte OnlineDoc. • Look for: bietet vier Arten der Abfrage • at least one word in list ODER Verknüpfung (Standard) all the words in list UND Verknüpfung the phrase Der genaue Ausdruck the advanced query Beliebige Verknüpfung mit NOT, AND, OR und Klammern Words: Suchbegriffe, Jokerzeichen * und ? erlaubt Kleingeschriebene Worte werden in jeder Schreibweise gefunden. z.B. format Ö format, Format, FORMAT Alle anderen Schreibweisen führen zu einer exakten Suche. z.B. Format Ö Format / format, FORMAT Folgende Sonderzeichen werden ignoriert: $, Punkt, Unterstrich Beispiele: ddmmyyw "means procedure" mean functions (all the words in list) functions dictionary categor* (all the words in list) Weitere Beispiele und Details in der Help Lasche. SAS Hilfe, Stürzl, Januar 08/Sashilfe.doc 5 SAS Hilfe Online Hilfe Version 8 3. Online Hilfe Version 8 Die mit Version 8 im SAS System integrierte Online Hilfe basiert auf der neuen HTMLHelp Technologie von Microsoft und wird mit einem eigenen Browser angezeigt. Dieser beinhaltet verbesserte Index- und Suchfunktionen. Der Aufruf erfolgt über das Help Menü Help Î SAS System Help, das Symbol in der Symbolleiste oder das Kommando [help]. Hilfe zu bestimmten SAS Fenstern z.B. Enhanced Editor, Explorer. Dazu das entsprechende Fenster aktivieren und Help Î Using This Window aufrufen. Für Hilfe zu einer bestimmten Prozedur im Enhanced Editor den Cursor auf den Prozedurenamen setzen und F1 drücken oder über das Kommando [help Prozedurname] z.B. [help univariate]. Lesezeichen können über die Favoriten Lasche definiert werden. Eingangshilfemaske der Inhalt-Lasche unter Help/SAS System Dies ist für die meisten Fragen der beste Einstieg in die Online Hilfe (entspricht dem Aufruf der Datei SAS.HLP). Hilfreich kann auch der Zugang über die Index-Lasche des Hilfe-Fensters sein. SAS Hilfe, Stürzl, Januar 08/Sashilfe.doc 6 SAS Hilfe SAS Links 4. SAS Links • SAS Customer Support http://support.sas.com • Technical Support (TS) http://support.sas.com/techsup/ Direkter Kontakt zur SAS Hotline in Heidelberg per Telefon oder schriftlich per Web Formular http://support.sas.com/ctx/supportform SAS Hilfe, Stürzl, Januar 08/Sashilfe.doc 7 SAS Hilfe • SAS Links SAS Communities bieten interessante Resourcen nach Themenbereichen gebündelt, z.B. zu Base SAS http://support.sas.com/rnd/base/ • Tipps & Tricks http://support.sas.com/sassamples/archive.html SAS Hilfe, Stürzl, Januar 08/Sashilfe.doc 8 SAS Hilfe • SAS Links SAS Institute Deutschland in Heidelberg http://www.sas.de • Die Statistik Seite des Rechenzentrums der Uni Heidelberg enthält sehr viele interessante Links zu Thema SAS und wird regelmäßig gepflegt (Dr. Carina Ortseifen). Diese Seite stellt damit einen guten Einstieg zum Thema SAS dar. http://web.urz.uni-heidelberg.de/statistik/ • Im SAS-Anwenderhandbuch im Netz (SAS-Ah) werden an der Praxis orientierte, von Anwendern verfasste Anleitungen und Dokumentationen zur SAS-Software gesammelt und den anderen SAS-Anwendern Online zur Verfügung gestellt. Die meisten Dokumente sind auf Deutsch verfasst. http://web.urz.uni-heidelberg.de/statistik/sas-ah SAS Hilfe, Stürzl, Januar 08/Sashilfe.doc 9 SAS Hilfe • SAS Links Konferenz der SAS Anwender in Forschung und Entwicklung (KSFE). Die seit 1997 jährlich stattfindende KSFE versteht sich als Forum für deutschsprachige SAS-Anwender aus dem Hochschul- und Forschungsbereich, deren Schwerpunkt bei der Anwendung im Bereich Datenanalyse liegt. http://www.ksfe.de • Views (The Independent UK SAS User Group) ist der Name einer aktiven Gruppe von SAS Anwendern aus Großbritannien, die einen sehr interessanten Newsletter herausgeben. http://www.views-uk.org • The Missing Semicolon, Technical Assistance for the SAS Software Professional ist ein regelmäßig erscheinender und lesenswerter Newsletter der US Firma Systems Seminar Consultants Inc., welcher auch per eMail abonniert werden kann. http://www.sys-seminar.com • NOTE: ist ein interessanter Newsletter von Andrew Ratcliffe, RTSL, England. "NOTE: is a free email newsletter for SAS practitioners. It contains hints, tips, and experience that are of interest to a wide range of SAS practitioners. NOTE: is published on an irregular basis" http://www.ratcliffe.co.uk/note_colon/ • Umfangreiche Seiten zum Thema SAS der US Firma InterNext http://www.sashelp.com/ • Allgemeine und praxisorientierte Einführung in die Statistik mit interessanten Beispielen und wichtigen Hinweisen von Dr. Andreas Christmann, Hochschulrechenzentrum der Uni Dortmund http://www.hrz.uni-dortmund.de/A1/kurse/unterlag/stat/stat.html • Statistik Tutorial, "Datenauswertung in der Physikalischen Chemie" http://barolo.ipc.uni-tuebingen.de/pharma/index.html • Alphabetische Referenzliste statistischer Schlüsselworte von SAS Institute http://support.sas.com/techsup/faq/stat_key/a_j.html • Akademie der Ruhr-Universität gGmbH mit dem Zentrum Biometrie http://www.akademie.ruhr-uni-bochum.de • Ruhr-Universität Bochum mit Links zur Stadt http://www.ruhr-uni-bochum.de SAS Hilfe, Stürzl, Januar 08/Sashilfe.doc 10 SAS Hilfe SAS Diskussionsforen 5. SAS Diskussionsforen 5.1. SAS-L SAS-L ist weltweit das größte Diskussionsforum von SAS Anwendern im Internet, welches unabhängig von SAS Institute an der Universität von Georgia in Athens, USA geführt wird. Die Liste besteht seit 1986 und hat ca. 2000 (1999) Teilnehmer aus über 40 Ländern. Gelesen wird das Forum jedoch von wesentlich mehr Menschen z.B. über das USENET. Hier wird über alles "gesprochen" was im weitesten Sinne mit SAS zu tun hat, z.B. Allgemeine Probleme und Lösungen zu allen Plattformen der SAS Software, statistische Fragestellungen und ihre Umsetzung, Verbesserungsvorschläge für die SAS Software, Neues über SI, Stellenangebote, ... Jeder Teilnehmer kann seinen Beitrag als Email an die Liste schicken, welche vom Listserver automatisch an alle übrigen Teilnehmer verteilt wird. Mit einer gewissen Zeitverzögerung sind alle Mails von SAS-L auch in folgender USENET Newsgroup zu sehen comp.soft-sys.sas Um einen Eindruck von dieser Newsgroup zu bekommen, empfiehlt sich der Zugang über Google Groups http://groups.google.com. Um an SAS-L teilzunehmen, muss man sich beim Listserver anmelden, indem man eine Email mit dem Befehl subscribe sas-L (Betreff bleibt frei) an folgende Adresse schickt: [email protected] subscribe sas-L <zweiteiliger Name> Anmelden an der Liste SAS-L. Wird <zweiteiliger Name> weggelassen, so wird die vollständige Email Adresse verwendet. Anschließend erhält man eine Bestätigungsnachricht, die man beantworten muss. Danach ist man in die Liste aufgenommen und erhält automatisch alle verteilten Nachrichten. unsubscribe sas-L Abmelden an der Liste SAS-L help Kurze Beschreibung der wichtigsten Listserverbefehle Die Adresse der Liste lautet: [email protected] ACHTUNG: Alle Mails, die an die Liste geschickt werden, werden an alle Teilnehmer weitergeleitet, sie dürfen deshalb keine Listserver Befehle beinhalten! Die Liste SAS-L besteht seit 1986 und ist bekannt für ihre rege Aktivität (50 Mails pro Tag sind keine Seltenheit, im langjährigen Durchschnitt 27 pro Tag). Im Interesse aller Teilnehmer sollten folgende Regeln beachtet werden: • • • • Die Nachrichten sollten in klarem und einfachem Englisch verfaßt sein. Das Thema sollte sachlich beschrieben werden. Jede Nachricht sollte eine aussagekräftige Betreffzeile haben. Jede Nachricht sollte Name, Adresse ggfs. Telefon und Email Adresse des Absenders beinhalten. Für Neulinge ist es empfehlenswert, die Gepflogenheiten der Liste über mehrere Tage zu beobachten. SAS Hilfe, Stürzl, Januar 08/Sashilfe.doc 11 SAS Hilfe SAS Diskussionsforen Listen Archiv Alle Mails, die über SAS-L verbreitet wurden, sind vom Listserver archiviert und stehen für detaillierte Recherchen zur Verfügung (ca. 12.000 pro Jahr seit 1994). So kann es sehr sinnvoll sein, zuerst das Archiv zu durchsuchen, bevor man sich mit einem bestimmten Problem an die Liste wendet. Möglicherweise ist dieses Problem in der Liste erst kürzlich diskutiert worden. Zwei Möglichkeiten für die web-basierte Archivrecherche: 1. Archives of [email protected] Die Universität von Georgia, an der auch die Liste SAS-L beheimatet ist, bietet einen Archiv Service ab 1996 an. Die Mails werden wöchentlich archiviert und können bequem durchsucht werden. http://www.listserv.uga.edu/archives/sas-l.html 2. Newsgroups Suche von Google http://groups.google.com/advanced_group_search SAS Hilfe, Stürzl, Januar 08/Sashilfe.doc 12 SAS Hilfe 5.2. SAS Diskussionsforen Redscope http://www.redscope.org Redscope ist die erste offene, deutschsprachige Kommunikationsplattform zur SAS-Software. Redscope ermöglicht es allen Anwender der SAS-Software, aktuell und praxisnah Fragen zur Programmierung und Anwendung zu stellen, Tips & Tricks auszutauschen. Redscope bietet: • Mehrere Foren für verschiedene Zielgruppen z.B. „Allgemeine Fragen zu SAS“, „Reporting & Visualisierung“, „Statistik & Data Mining“ • Einzelne Foren oder Beitrage lassen sich abonnieren, d. h. man erhält automatisch eine Benachrichtigung per Email, sobald neue Beiträge erschienen sind. • eine Datenbank registrierter Mitglieder, über die Mitglieder miteinander in Kontakt treten können. • einen Projekt-Bereich, in dem gemeinsam an Dokumentationen oder (Open-Source)-Tools gearbeitet werden kann, Redscope.org ist nicht als Sammlung anonymer Beiträge angelegt, sondern versteht sich als ein Teil des "Social Web", d.h. eines offenen globalen und verteilten Netzwerks zum Austausch von Informationen auf der Basis des Internets. Im Gegensatz zum klassischen Internet steht nicht die Verlinkung von Dokumenten im Vordergrund, sondern die Verlinkung von Menschen, Organisationen und Ideen. SAS Hilfe, Stürzl, Januar 08/Sashilfe.doc 13 SAS Hilfe 5.3. SAS Diskussionsforen User Forums von SAS Institute Seit 2006 hat SAS Institute auf seinen Webseiten verschiedene User Discussion Forums eingerichtet. http://support.sas.com/forums 5.4. SAS-EDU Die deutschsprachige Diskussionsliste SAS-EDU des Universitätsrechenzentrums Heidelberg wurde als Diskussionsforum eingerichtet für den Austausch von Informationen zur Ausbildung in und mit SAS. Außerdem werden über die Liste Neuerungen im SAS-Anwenderhandbuch im Netz (SAS-AH) angekündigt, sowie Beiträge für das SAS-AH diskutiert. Listserver ist: [email protected] Zur Anmeldung folgende Email an den Listserver schicken (Betreff leer): subscribe sas-edu Vorname Nachname Mehr Details unter: http://web.urz.uni-heidelberg.de/statistik/sas-ah/sas-edu.html 5.5. Deutsches SAS-Forum Seit 1997 gibt es das deutschsprachige webbasierte SAS Forum der Firma dibera DV- und WirtschaftsberatungsGmbH in Münster. Es versteht sich als ein nicht-kommerzielles Nachrichten- und Diskussionsforum zu allen SASThemen von Anwendern für Anwender. http://www.dibera.de/sas-forum/inhalt.html SAS Hilfe, Stürzl, Januar 08/Sashilfe.doc 14 SAS Hilfe SAS Institute Listserver 6. SAS Institute Listserver Die Abteilung „Technical Support“ (TS) von SAS Institute (SI) in Cary, North Carolina, USA unterhält einen Listserver, von dem man via Email automatisch über Neuigkeiten informiert wird. Die Adresse lautet: [email protected] Der Listserver verwaltet u. a. die folgenden Listen • • TSDOCS-L Hinweis auf neue TS Dokumente auf den Web-Seiten von SI DDOCNEWS-L Hinweis auf neue Dokumente von SI, u. a. neue Artikel der Web-Zeitschrift "Observation - The Technical Journal for SAS Software Users", neue Bücher von SI, etc. herausgegeben von SI Deutschland • TSSASNOTES-L Tagesaktuelle Hinweise auf neue und überarbeitete SAS Notes auf den Web-Seiten von SI Mit folgenden Befehlen, die im Text einer Mail (Betreff bleibt frei) an den Listserver gesendet werden, erhält man Informationen über den Listserver und seine Listen. Eine Mail kann mehrere Befehle enthalten, die jeweils in einer neuen Zeile stehen müssen. help Kurze Beschreibung der wichtigsten Befehle subscribe listen-name <zweiteiliger Name> Anmelden an einer Liste. Wird <zweiteiliger Name> weggelassen, so wird die vollständige Email Adresse verwendet. signoff listen-name SAS Hilfe, Stürzl, Januar 08/Sashilfe.doc Abmelden an einer Liste 15 SAS Hilfe Übung: SAS Hilfe 7. Übung: SAS Hilfe 1. Suchen Sie in der SAS Online Hilfe folgende Themen: Prozedur TRANSPOSE Anweisung MERGE Funktion MEDIAN System Option MSGLEVEL= 2. Suchen Sie in den Web Seiten von SAS Institute nach folgenden Themen: error by variables are not properly sorted different ways to merge data sets SAS Hilfe, Stürzl, Januar 08/Sashilfe.doc 16 Lösungsvorschläge *+------------+ Bestimmte SAS Tabellen generieren |uebung11.sas| +------------+ ; *FOOTNOTE1 "SAS Programmierung für Fortgeschrittene I Stürzl/9.9.96"; DATA a1; DO x1=1 TO 20; x2=10*x1; x3=x1+x2; x4=x1-0.5; x5=MOD(x1,2); OUTPUT; END; RUN; PROC PRINT DATA=a1; RUN; * Lösung mit RETAIN Anweisung (Tabelle a1 verwenden); DATA a21; SET a1 (KEEP=x1); RETAIN id; IF MOD(x1,2)=1 THEN id=x1; * nur bei ungeraden Zahlen id neuen Wert zuweisen; RUN; PROC PRINT DATA=a21; RUN; * Lösung mit LAG Funktion (Tabelle a1 verwenden); DATA a22; SET a1 (KEEP=x1); id=x1; hilf=LAG(x1); IF MOD(x1,2)=0 THEN id=hilf; * bei geraden Zahlen Vorgängerwert zuweisen; DROP hilf; RUN; PROC PRINT DATA=a22; RUN; *+------------+ Vertikale Mittelwertbildung (über Observations) |uebung12.sas| +------------+ ; *FOOTNOTE1 "SAS Programmierung für Fortgeschrittene I Stürzl/2.5.00"; * DATA STEP Lösung mit LAG-Funktion; DATA mess; SET a21; lagx1=LAG(x1); IF MOD(_N_,2)=0 THEN DO; * IF id=LAG(id) THEN DO; * IF LAST.id THEN DO; /* setzt Sortierung nach Variable id und Anweisung BY id; voraus */ mx1=MEAN(x1,lagx1); diff=mx1-id; SAS Programmierung für Fortgeschrittene I; Stürzl; Oktober 06/LOEFRT1.DOC 1 Lösungsvorschläge END; ELSE DELETE; RUN; PROC PRINT DATA=mess; RUN; * Lösung PROC MEANS; PROC SORT DATA=a21; BY id; RUN; PROC MEANS DATA=a21 NOPRINT; VAR x1; OUTPUT OUT=stat1 MEAN=mx1; BY id; RUN; DATA mess; MERGE a21 stat1; BY id; diff=mx1-id; IF MOD(_N_,2)=0; * nur jede zweite Beobachtung behalten; RUN; PROC PRINT DATA=mess; RUN; *+------------+ Normalgewichtstabelle |uebung13.sas| +------------+ ; *FOOTNOTE1 "SAS Programmierung für Fortgeschrittene I Stürzl/21.8.00"; TITLE1 "Normalgewichtstabelle nach Body Mass Index (19 bis 25)"; DATA normal; DO laenge=1.50 TO 2.00 BY 0.01; min_gew=19*laenge**2; max_gew=25*laenge**2; OUTPUT; END; FORMAT min_gew max_gew 3.; LABEL laenge ="Länge [m]" min_gew="Minimalgewicht [kg]" max_gew="Maximalgewicht [kg]" ; RUN; OPTIONS PAGENO=1; PROC PRINT DATA=normal LABEL NOOBS; VAR laenge min_gew max_gew; RUN; * Hochauflösende Grafik; GOPTIONS FTEXT=SWISS; SYMBOL1 C=BLACK V=NONE I=JOIN L=2; * gestrichelte Linie; SYMBOL2 C=BLACK V=NONE I=JOIN L=1; * durchgezogene Linie; PROC GPLOT DATA=normal; PLOT min_gew*laenge max_gew*laenge / OVERLAY GRID; RUN; QUIT; SAS Programmierung für Fortgeschrittene I; Stürzl; Oktober 06/LOEFRT1.DOC 2 Lösungsvorschläge *+---------------+ Selektion von Beobachtungen |uebung31-36.sas| +---------------+ ; *FOOTNOTE1 "SAS Programmierung für Fortgeschrittene I Stürzl/7.9.00"; *** Übung 31 ***; DATA neu; SET alt (obs=10); RUN; DATA neu; SET alt; IF _N_<=10; RUN; *** Übung 32 ***; DATA frauen; SET kino; WHERE sex^="1"; * IF sex^="1"; * WHERE NOT (sex="1"); * IF NOT (sex="1"); RUN; *** Übung 33 ***; WHERE telefon IN: ("089" "040"); WHERE UPCASE(antwort1)="NEIN"; *** Übung 34 ***; WHERE sex="w" AND .<gebdatum<"01jan1920"d AND (ort="München" OR ort="Hamburg"); * oder; WHERE sex="w" AND .<gebdatum<"01jan1920"d AND ort IN ("München" "Hamburg"); * oder; WHERE sex="w" AND .<YEAR(gebdatum)<1920 AND ort IN ("München" "Hamburg"); * Nachteil vieler mit AND verknüpfter Bedingungen ist, dass immer alle Bedingungen geprüft werden, auch dann wenn eine Bedingung nicht erfüllt ist und die Prüfung der restlichen Bedingung sinnlos ist. Der Vorteil von geschachtelten Subsetting IFs ist, dass keine weiteren Bedingunen geprüft werden, sobald eine Bedingung nicht erfüllt ist. Dabei ist es effizienter die "seltensten" Bedingung, d. h. die am seltensten erfüllt sind, an den Anfang zu stellen, weil die nachfolgenden Bedingung nur in diesen Fällen überhaupt geprüft werden; IF .<YEAR(gebdatum)<1920 THEN IF ort IN ("München" "Hamburg") THEN IF sex="w"; *** Übung 35 ***; WHERE messdat<0; * findet negative und fehlende Ausprägungen; *** Übung 36 ***; IF NOT (x=100 OR y=100); IF x^=100 AND y^=100; SAS Programmierung für Fortgeschrittene I; Stürzl; Oktober 06/LOEFRT1.DOC 3 Lösungsvorschläge *+-------------+ DOS Directory Listing ("dir > Dateiname") als Textdatei lesen |uebung41a.sas| +-------------+; *FOOTNOTE1 "SAS Programmierung für Fortgeschrittene I Stürzl/12.10.04"; LIBNAME kurs "F:\SASKurs"; DATA kurs.dirlist; INFILE "F:\saskurs\dir.txt" firstobs=6; * Ab dem 6. Record lesen; INPUT datum:ddmmyy10. zeit:time5. @26 dir $3. @; * Einlesepointer in der Zeile halten!; IF dir="DIR" THEN INPUT @40 name:$255.; ELSE INPUT groesse:commax. name:$255.; IF MISSING(datum) THEN DELETE; * Fußzeilen löschen; FORMAT datum DATE9. zeit HHMM5.; RUN; PROC PRINT DATA=kurs.dirlist; RUN; *+-------------+ DOS Directory Listing ("dir > Dateiname") als Textdatei lesen |uebung41b.sas| Name des gelisteten Dateiverzeichnisses in jeder Beobachtung +-------------+ Vollständiger Dateiname mit Laufwerk und Pfad; *FOOTNOTE1 "SAS Programmierung für Fortgeschrittene I Stürzl/12.10.04"; LIBNAME kurs "F:\SASKurs"; *** Lösung 1 mit Input Buffer _INFILE_ für variable Länge des Pfadnamens ***; DATA kurs.dirlist; INFILE "F:\saskurs\dir.txt"; LENGTH pfadname $255; * Maximale Länge unter Windows; RETAIN pfad; INPUT hilf $3. @; * Einlesepointer in der Zeile halten!; IF hilf IN ("Da" "") THEN DELETE; * Nicht benötigte Header- und Fusszeilen; ELSE IF hilf IN ("Ve") THEN pfad=substr(_infile_,17); * Input buffer wegen variabler Länge nutzen, da Pfade Blanks enthalten können ist List Input mit Trennzeichen Blank problematisch; ELSE DO; * Einträge lesen; INPUT @1 datum:ddmmyy10. zeit:time5. @26 dir $3. @; * Einlesepointer in der Zeile halten!; IF dir="DIR" THEN INPUT @40 name:$255.; ELSE INPUT groesse:commax. name:$255.; END; IF hilf="Ve" THEN DELETE; * Obs. kann nachträglich gelöscht werden; pfadname=trim(pfad)||"\"||name; * kompletter Name; FORMAT datum DATE9. zeit HHMM5.; DROP hilf name pfad; RUN; *** Lösung 2 mit $VARYING Informat für variable Länge des Pfadnamens ***; DATA kurs.dirlist; INFILE "F:\saskurs\dir.txt" LENGTH=reclen; LENGTH pfadname $255; * Maximale Länge unter Windows; RETAIN pfad; INPUT hilf $3. @; * Einlesepointer in der Zeile halten!; IF hilf IN ("Da" "") THEN DELETE; * Nicht benötigte Header- und Fusszeilen; ELSE IF hilf IN ("Ve") THEN DO; INPUT @; * erzeugt den Input buffer und schreibt die Recordlänge in die Variable reclen; SAS Programmierung für Fortgeschrittene I; Stürzl; Oktober 06/LOEFRT1.DOC 4 Lösungsvorschläge hilf2=reclen-17; * Tatsächliche Länge des Pfades; INPUT @18 pfad $varying255. hilf2; * $varying Informat für variable Länge; END; ELSE DO; * Einträge lesen; INPUT @1 datum:ddmmyy10. zeit:time5. @26 dir $3. @; * Einlesepointer in der Zeile halten!; IF dir="DIR" THEN INPUT @40 name:$255.; ELSE INPUT groesse:commax. name:$255.; END; IF hilf="Ve" THEN DELETE; * Obs. kann nachträglich gelöscht werden; pfadname=trim(pfad)||"\"||name; * kompletter Name; FORMAT datum DATE9. zeit HHMM5.; DROP hilf: name pfad; RUN; PROC SORT DATA=kurs.dirlist; BY dir pfadname; * Dateien vor Verzeichnissen, jeweils sortiert; RUN; PROC PRINT DATA=kurs.dirlist; VAR pfadname dir groesse datum zeit; RUN; *+------------+ Aus EXCEL-Tabelle Daten einlesen |uebung42.sas| Fortsetzung in Übung54 +------------+ ; *FOOTNOTE1 "SAS Programmierung für Fortgeschrittene I LIBNAME kurs "F:\SASKurs"; Stürzl/9.9.96 01-06-01"; FILENAME daten DDE 'excel|F:\saskurs\messtab1.xls!Z3S1:Z12S10'; DATA kurs.messtab1; INFILE daten DLM='09'x NOTAB DSD MISSOVER; INFORMAT id $4. datum YYMMDD6. p1g1-p1g4 COMMAX.; INPUT id datum p1g1-p1g4 p2g1-p2g4; IF NOT missing(id); FORMAT datum DATE9.; RUN; PROC SORT DATA=kurs.messtab1; BY id datum; RUN; PROC PRINT DATA=kurs.messtab1; RUN; SAS Programmierung für Fortgeschrittene I; Stürzl; Oktober 06/LOEFRT1.DOC 5 Lösungsvorschläge *+------------+ Verknüpfung von SAS Tabellen |uebung51.sas| +------------+ ; *FOOTNOTE1 "SAS Programmierung für Fortgeschrittene I Stürzl/9.9.96"; DATA x; a=100; RUN; DATA y; DO b=1 TO 5; OUTPUT; END; RUN; *-----------------------------------------------------------------------------; DATA xy1; SET x (RENAME=(a=b)) y; PUT _ALL_; RUN; *-----------------------------------------------------------------------------; DATA xy2; SET x; SET y; PUT _ALL_; RUN; DATA xy2; MERGE x y; IF _N_=1; PUT _ALL_; RUN; DATA xy2; MERGE x y (OBS=1); PUT _ALL_; RUN; *-----------------------------------------------------------------------------; DATA xy3; SET x; SET y (WHERE=(b=3)); * SET y (FIRSTOBS=3); PUT _ALL_; RUN; DATA xy3; MERGE x y (WHERE=(b=3)); PUT _ALL_; RUN; *-----------------------------------------------------------------------------; DATA xy4; IF _N_=1 THEN SET x; SET y; PUT _ALL_; RUN; DATA xy4; RETAIN a; MERGE x (RENAME=(a=hilf)) y; IF _N_=1 THEN a=hilf; PUT _ALL_; SAS Programmierung für Fortgeschrittene I; Stürzl; Oktober 06/LOEFRT1.DOC 6 Lösungsvorschläge RUN; DATA x1; SET x; hilf=1; RUN; * künstliche BY-Variable zum Mergen bilden; DATA y1; SET y; hilf=1; RUN; * künstliche BY-Variable zum Mergen bilden; DATA xy4; MERGE x1 y1; BY hilf; PUT _ALL_; RUN; *+------------+ prozentualen Anteil der Dateigröße im Dateiverzeichnis berechnen |uebung52.sas| +------------+ ; *FOOTNOTE1 "SAS Programmierung für Fortgeschrittene I Stürzl/29.9.97"; LIBNAME kurs "F:\SASKurs"; PROC SORT DATA=kurs.dirlist; BY dir; RUN; PROC MEANS DATA=kurs.dirlist noprint; VAR groesse; OUTPUT OUT=stat1 SUM=gesamt; * Gesamtgröße; BY dir; RUN; *------------- Lösungvorschlag 1: MERGE BY -------------------; DATA dirlist; MERGE kurs.dirlist stat1; BY dir; WHERE dir=""; * nur Dateien; relgroes=100*groesse/gesamt; FORMAT relgroes 5.1; RUN; *------------- Lösungvorschlag 2: MERGE ohne BY Variable -------------; DATA dirlist; IF _N_=1 THEN SET stat1; * MERGE mit AutoRetain; SET kurs.dirlist; IF dir=""; * nur Dateien; relgroes=100*groesse/gesamt; FORMAT relgroes 5.1; RUN; PROC PRINT DATA=dirlist; VAR pfadname groesse relgroes gesamt datum zeit; RUN; *------------- Lösungvorschlag 3: PROC FREQ -------------------; PROC FREQ DATA=kurs.dirlist; WHERE dir=""; * nur Dateien; TABLES pfadname; WEIGHT groesse; RUN; SAS Programmierung für Fortgeschrittene I; Stürzl; Oktober 06/LOEFRT1.DOC 7 Lösungsvorschläge *+------------+ Zeitliche Abstände zur ersten Messung einer ID |uebung54.sas| Fortsetzung von Übung42 +------------+ ; *FOOTNOTE1 "SAS Programmierung für Fortgeschrittene I Stürzl/9.9.96 26.9.98"; LIBNAME kurs "F:\SASKurs"; PROC SORT DATA=kurs.messtab1; BY id datum; RUN; *--------------- Lösungsvorschlag 1: Mit RETAIN -------------------------------; DATA mess2; SET kurs.messtab1; BY id; RETAIN datum0; IF FIRST.id THEN datum0=datum; * IF id^=LAG(id) THEN datum0=datum; tage=datum-datum0; * Differenz der Tage seit erster Messung; RUN; *------ Lösungsvorschlag 2: Hilfstabelle mit 1 Obs. pro By-Gruppe -------------; DATA hilf; SET kurs.messtab1; IF id^=LAG(id); * erste Beobachtung einer BY-Gruppe; RENAME datum=datum0; KEEP id datum; * wichtig für MERGE!; RUN; DATA mess2; MERGE kurs.messtab1 hilf; BY id; tage=datum-datum0; * Differenz der Tage seit erster Messung; RUN; TITLE2 "Differenz der Meßzeitpunkte"; PROC PRINT DATA=mess2; VAR datum tage p1g1-p1g4 p2g1-p2g4; BY id; ID id; RUN; SAS Programmierung für Fortgeschrittene I; Stürzl; Oktober 06/LOEFRT1.DOC 8 Lösungsvorschläge *+------------+ Dublettencheck |uebung55.sas| Liste aller mehrfach vorkommenden Schlüssel +------------+ ; *FOOTNOTE1 "SAS Programmierung für Fortgeschrittene I Stürzl/24-5-99"; TITLE1 "Dublettencheck - Liste aller mehrfach vorkommenden Schlüssel"; PROC SORT DATA=kurs.bwahl2; BY wkreis jahr stimme; RUN; *******************************************************************; * Lösungsansatz1: Nicht eindeutige Schlüssel direkt erkennen; DATA check3; SET kurs.bwahl2; BY wkreis jahr stimme; IF NOT (FIRST.stimme AND LAST.stimme); RUN; PROC PRINT DATA=check3; VAR wberecht gueltig spd cdu csu gruene fdp pds; BY wkreis jahr stimme; RUN; *******************************************************************; * Lösungsansatz2: Nicht eindeutige Schlüssel direkt erkennen und nummerieren; DATA check3; SET kurs.bwahl2; BY wkreis jahr stimme; IF FIRST.stimme AND LAST.stimme THEN mehrfach=0; ELSE mehrfach+1; IF mehrfach>0; RUN; PROC PRINT DATA=check3; VAR mehrfach wberecht gueltig spd cdu csu gruene fdp pds; BY wkreis jahr stimme; RUN; *******************************************************************; * Lösungsansatz3: Alle Ausprägungen von mehrfachen Schlüsseln listen Obs. pro Schlüssel nummerieren (FIRST.variable) und Gesamtanzahl finden Vorteil: Zwei neue Variablen, die die weitere Verarbeitung der verschiedenen Dubletten (z.B. Löschen) erleichtern; TITLE2 "Alle Ausprägungen von mehrfachen Schlüsseln"; *** Variante 1: Maximum mit PROC MEANS; DATA check1; SET kurs.bwahl2; BY wkreis jahr stimme; IF FIRST.stimme THEN nr=0; nr+1; * Obs. nummerieren; SAS Programmierung für Fortgeschrittene I; Stürzl; Oktober 06/LOEFRT1.DOC 9 Lösungsvorschläge RUN; PROC MEANS DATA=check1 NOPRINT; VAR nr; OUTPUT OUT=check2 MAX=anzahl; * Gesamtanzahl von Obs. pro Schlüssel; BY wkreis jahr stimme; RUN; *** Variante 2: DATA Step Lösung ohne Prozedur; /* DATA check1 (DROP=anzahl) check2 (KEEP=wkreis jahr stimme anzahl); SET kurs.bwahl2; BY wkreis jahr stimme; IF FIRST.stimme THEN nr=0; nr+1; * Obs. nummerieren; IF LAST.stimme THEN DO; anzahl=nr; OUTPUT check2; * Gesamtanzahl von Obs. pro Schlüssel; END; OUTPUT check1; RUN; */ DATA check3; MERGE check1 check2; BY wkreis jahr stimme; IF anzahl > 1; * Schlüssel mit mehr Obs. als erwartet; RUN; PROC PRINT DATA=check3; VAR anzahl nr wberecht gueltig spd cdu csu gruene fdp pds; BY wkreis jahr stimme; * ID wkreis jahr stimme; RUN; *+------------+ Dubletten löschen |uebung56.sas| Alle mehrfach vorkommenden Schlüssel löschen +------------+ ; *FOOTNOTE1 "SAS Programmierung für Fortgeschrittene I Stürzl/24-5-99"; TITLE1 "Dubletten löschen - Alle mehrfach vorkommenden Schlüssel löschen"; * 1. Lösungsansatz: Blind löschen Ausschließlich die erste Ausprägung behalten, alle übrigen Obs. verwerfen mit NODUPKEY Option von PROC SORT. Gelöschte Obs. in separater Tabelle speichern mit DUPOUT Option; PROC SORT DATA=kurs.bwahl2 OUT=bwahl NODUPKEY DUPOUT=geloescht; BY wkreis jahr stimme; RUN; * 2. Lösungsansatz: Gezielt löschen mit Abfrage der unerwünschten Obs. (setzt Nummerierung zur Unterscheidung der Obs. voraus (siehe Lösungsansatz 1 von Übung55)); DATA bwahl; MERGE check1 check2; BY wkreis jahr stimme; SAS Programmierung für Fortgeschrittene I; Stürzl; Oktober 06/LOEFRT1.DOC 10 Lösungsvorschläge IF gueltig=. THEN DELETE; * IF anzahl > 1 THEN DELETE; RUN; *+------------+ ¦uebung61.sas¦ +------------+ ; *FOOTNOTE1 "SAS Summe quadratischer Abstände vom Mittel (corrected sum of squares) ==> Varianz, Standardabweichung Programmierung für Fortgeschrittene I Stürzl/30.9.97 26.9.98"; DATA css; ARRAY x [10]; * Initialisierung; DO i=1 TO DIM(x); x[i]=i; END; xquer=MEAN(OF x[*]); * Summe der quadratischen Abweichungen vom Mittelwert; DO i=1 TO DIM(x); css1 + (x[i] - xquer)**2; END; css2=CSS(OF x[*]); * zur Kontrolle; Varianz1=css1/(DIM(x)-1); Varianz2=VAR(OF x[*]); * zur Kontrolle; PUT _ALL_; RUN; *+------------+ Daten aus Tabelle s1 vertikal strukturieren wie in s2 |uebung71.sas| +------------+; *FOOTNOTE1 "SAS Programmierung für Fortgeschrittene I Stürzl/9.9.96, 23.9.98 27.10.02"; DATA s1; INFILE CARDS MISSOVER; INPUT patient $ puls_t1-puls_t3 temp_t1-temp_t3; CARDS; A 72 85 110 36.3 36.7 37.2 B 80 120 . 38.1 38.6 39.0 ; RUN; *-------------- Lösungsvorschlag1: Datenschritt elementar --------------; DATA s2; SET s1; zeit=1; puls=puls_t1; temp=temp_t1; OUTPUT; zeit=2; puls=puls_t2; temp=temp_t2; OUTPUT; zeit=3; puls=puls_t3; temp=temp_t3; OUTPUT; DROP puls_t1-puls_t3 temp_t1-temp_t3; RUN; PROC PRINT DATA=s2; RUN; *-------------- Lösungsvorschlag2: Datenschritt DO-Schleife, ARRAY -----; SAS Programmierung für Fortgeschrittene I; Stürzl; Oktober 06/LOEFRT1.DOC 11 Lösungsvorschläge DATA s2; SET s1; ARRAY puls_t [3]; ARRAY temp_t [3]; DO zeit=1 TO 3; puls=puls_t[zeit]; temp=temp_t[zeit]; OUTPUT; END; DROP puls_t1-puls_t3 temp_t1-temp_t3; RUN; PROC PRINT DATA=s2; RUN; *------------- Lösungsvorschlag mit PROC TRANSPOSE ---------------------; PROC SORT DATA=s1; BY patient; RUN; PROC TRANSPOSE DATA=s1 OUT=s21 PREFIX=puls; VAR puls_t1-puls_t3; BY patient; RUN; PROC TRANSPOSE DATA=s1 OUT=s22 PREFIX=temp; VAR temp_t1-temp_t3; BY patient; RUN; DATA s2_; MERGE s21 s22; BY patient; * ACHTUNG: Verknüpfung ist nicht eindeutig!; RUN; *--> NOTE: MERGE statement has more than one data set with repeats of BY values.; * Für eine eindeutige Verknüpfung wird eine weiteres Merkmal benötigt; * Vorschlag 1: Hilfsvariable 'Zeit' aus _NAME_ bilden ; DATA s21; SET s21; zeit=SUBSTR(_NAME_,6); RUN; DATA s22; SET s22; zeit=SUBSTR(_NAME_,6); RUN; DATA s2_; MERGE s21 s22; BY patient zeit; RUN; PROC PRINT DATA=s2_; RUN; * Vorschlag 2: Hilfsvariable 'Zeit' aus _LABEL_ bilden, dazu in der Ausgangstabelle für die zu transponierenden Variablen passende Labels definieren; DATA s1; SET s1; LABEL puls_t1="1" temp_t1="1" puls_t2="2" temp_t2="2" puls_t3="3" temp_t3="3"; RUN; PROC TRANSPOSE DATA=s1 OUT=s21 PREFIX=puls; SAS Programmierung für Fortgeschrittene I; Stürzl; Oktober 06/LOEFRT1.DOC 12 Lösungsvorschläge VAR puls_t1-puls_t3; BY patient; RUN; PROC TRANSPOSE DATA=s1 OUT=s22 PREFIX=temp; VAR temp_t1-temp_t3; BY patient; RUN; DATA s2_; MERGE s21 s22; BY patient _LABEL_; RUN; PROC PRINT DATA=s2_; RUN; *+------------+ Daten aus MESSTAB1.XLS vertikal strukturieren |uebung72.sas| Fortsetzung von Übung42 +------------+ ; *FOOTNOTE1 "SAS Programmierung für Fortgeschrittene I Stürzl/9.9.96"; **** DATA STEP Variante (zwei-dimensionales ARRAY) ****; DATA kurs.messtab2; SET kurs.messtab1; ARRAY m[2,4] p1g1-p1g4 p2g1-p2g4; DO param="Param 1", "Param 2"; DO geraet=1 TO 4; mess=m[substr(param,7),geraet]; OUTPUT; END; END; DROP p1g1-p1g4 p2g1-p2g4; RUN; PROC PRINT DATA=kurs.messtab2; RUN; **** PROC TRANSPOSE Variante ****; PROC SORT DATA=messtab2; BY id datum; RUN; PROC TRANSPOSE DATA=kurs.messtab1 OUT=messtab2; VAR p1g1-p1g4 p2g1-p2g4; BY id datum; RUN; PROC PRINT DATA=messtab2; RUN; SAS Programmierung für Fortgeschrittene I; Stürzl; Oktober 06/LOEFRT1.DOC 13 Lösungsvorschläge *+------------+ Fortsetzung und Umkehrung von Übung72 |uebung73.sas| Daten wieder horizontal strukturieren wie IN MESSTAB1.XLS +------------+ ; *FOOTNOTE1 "SAS Programmierung für Fortgeschrittene I Stürzl/9.9.96 23.9.98"; PROC SORT DATA=kurs.messtab2; BY id datum; RUN; DATA messtab0; ARRAY x [2,4] x1-x4 y1-y4; DO UNTIL (LAST.datum); SET kurs.messtab2; BY id datum; x[SUBSTR(param,7),geraet]=mess; END; DROP param geraet mess; RUN; PROC PRINT DATA=messtab0; RUN; * Lösung mit PROC TRANSPOSE; DATA messtab2; LENGTH par_ger $4; * eindeutige ID-Variable für Parameter und Gerät; SET kurs.messtab2; par_ger=COMPRESS("P"||PUT(param, 1.)||"G"||PUT(geraet, 1.)); RUN; PROC SORT DATA=messtab2; BY id datum; RUN; PROC TRANSPOSE DATA=messtab2 OUT=messtab0; VAR mess; BY id datum; ID par_ger; RUN; PROC PRINT DATA=messtab0; RUN; SAS Programmierung für Fortgeschrittene I; Stürzl; Oktober 06/LOEFRT1.DOC 14