Wprowadzenie do SAS Część II: Elementy języka SAS 4GL Rafał Latkowski Jak zacząć? 2 Enhanced Editor (1) Uruchamianie programu Zaznaczyć blok (lub bez zaznaczania, gdy chcemy wykonać całą zawartość pliku). Wcisnąć F3 lub 3 4 Definiowanie bibliotek Engine V8 : libname kurs c:\kurs ; Różnice pomiędzy interfejsem: Podłączanie przy starcie można uzyskać wpisując do autoexec.sas Engine V8 (domyślny) jest w pełni zgodny z V7-V9 oraz czyta automatycznie zbiory V6 Zbiory SAS mogą być skompresowane options compress=yes; 5 Ćwiczenie 3 Skasować bibliotekę kurs Założyć bibliotekę kurs bez pomocy interfejsu Założyć bibliotekę dane wskazującą na ten sam katalog. 6 1
Struktura programu w 4GL Wprowadzenie do SAS 4GL Program w 4GL składa się z: Proc Step ów Data Step ów Data Step y tworzą nowy zbiór danych (niekoniecznie) Proc Step y wykonują procedurę SAS (praktycznie nierozszerzalny zbiór procedur) Nie można zagnieżdżać proc stepów i data stepów w sobie (w dowolnej kombinacji) 7 8 Cechy 4GL SQL jest podzbiorem języka 4GL (proc sql; tam można zagnieżdżać wyrażenia SQL owe) SAS 4GL jest skomplikowany Posiada duże bogactwo opcji stosowalnych w wielu miejscach Posiada ogromną liczbę procedur o rozbudowanej funkcjonalności SAS 4GL jest prosty Jeżeli nie wiesz, jak coś zostało zaimplementowane, to zostało to zaimplementowane w najprostszy sposób (tj. tak aby uzyskać maksymalną efektywność). Data Step data <nazwa zbioru>; <zawartość data step a> 9 10 data a; Data Step pusty Tworzy pusty zbiór (1 obserwacja, 0 zmiennych); Domyślnie zbiór utworzony zostanie w bibliotece work (data a; === data work.a;) data a; Data Step kopiujący set kurs.noty; Kopiuje zbiór określony w poleceniu set do zbioru określonego w nagłówku data step a; 11 12 2
Ćwiczenie 4 Skopiować zbiór kurs.noty do biblioteki dane pod dowolną nazwą (np. dane.kopia) Porównać, czy zbiór jest widoczny również w bibliotece kurs (ew. użyć opcji View/Refresh ) Sprawdzenie nazw kolumn (1) Nazwy kolumn można sprawdzić w oknie properties zbioru danych (prawy przycisk myszy na zbiorze). Nazwy kolumn można sprawdzić w VIEWTABLE, ale uwaga: należy odróżnić nazwy od label i. 13 14 Sprawdzenie nazw kolumn (2) Proc Step opis zbioru (1) proc contents data=kurs.noty; Wypisuje informacje o zbiorze w oknie Out (czyli jest to tzw. raport). 15 16 Proc Contents (2) proc contents data=kurs.noty short; Proc Step - sortowanie proc sort data=kurs.iris out=kurs.iris_sorted; by sepallen sepalwid; Opcja short powoduje, że wypisywane są tylko nazwy zmiennych. 17 Sortuje zbiór w.g. podanych zmiennych. Można również bez out=, wtedy nadpisuje zbiór data=. Uwaga: Zbiór otwarty (np. w VIEWTABLE) nie może być nadpisany (to dotyczy również data step ów). 18 3
PROC SORT Syntax (doc) Opcje procedury SORT (doc) Syntax PROC SORT <option(s)> <collatingsequence-option>; BY <DESCENDING> variable-1 <...<DESCENDING> variable-n>; Specify the output order Reverse the order for character variables Maintain the order within BY groups Allow for variation within BY groups REVERSE EQUALS NOEQUALS Dokumentacja: F1 http://v8doc.sas.com/sashtml/ 19 Eliminate duplicate observations Delete observations with common BY values Delete observations that have duplicate values NODUPKEY NODUPRECS 20 Ćwiczenie 5 Proc SQL Posortować zbiór Kurs.Noty (np. do Kurs.Noty2), tak aby ostatnie ( najmłodsze ) notowania znalazły się na początku zbioru. Posortować zbiór Kurs.Noty jak powyżej; W zbiorze wynikowym (np. Kurs.Noty3) powinna się znaleźć tylko jedna obserwacja (notowanie) z każdego dnia. proc sql; create table kurs.noty3s as select * from kurs.noty where nazwa='tonsil' order by data desc; quit; 21 22 Wczytanie zbioru wewnętrznego Proste techniki wczytywania data klasa; input imie $ nazwisko $ wiek; Jan Kowalski 8 Ola Wokalska 9 Wit Lokawski 8 ; run; 23 24 4
Wczytywanie problemy (1) Wczytywanie problemy (2) data klasa; input imie $ nazwisko $ wiek; Jan Kowalski 8 Ola Wokalska 9 Wit Lokawski 8 Aleksander Mucha 10 25 26 Wczytywanie problemy (3) Wczytywanie rozwiązanie data klasa; length imie $10; input imie $ nazwisko $ wiek; Jan Kowalski 8 Ola Wokalska 9 Wit Lokawski 8 Aleksander Mucha 10 27 28 Length Analogicznie można napisać: length wiek 8; length wiek 4; length nazwisko $20; Wczytywanie zbioru z pliku data kan; infile 'c:\kurs\txt\kan.txt'; input plec wiek zawod miejsce_zam rozpoznanie uzaleznienie_lat ilosc_wyp_papierosow poprzednie_proby choroby_ukl_kraz choroby_ukl_kraz_ob choroby_ukl_oddech choroby_wrzody choroby_psychiczne choroby_nerwice ilosc_zab_elektro czas_trw_obserw efekty_leczenia dzialania_uboczne; 29 30 5
Etykiety label plec='płeć' wiek='wiek' zawod='zawód' miejsce_zam="miejsce zamieszkania" rozpoznanie="rozpoznanie" uzaleznienie_lat="czas uzależnienia w latach"; label ilosc_wyp_papierosow="ilość wypalanych papierosów przed kuracją"; Label, length, format, input, set Nie jest wszystko jedno w jakiej kolejności pojawiają się te instrukcje wstawić label na początek data step u np. dla zmiennej zawod Jeżeli nie jest wyspecyfikowane inaczej, domyślnie zmienna jest typu numerycznego i długości 8 (bajtów-n, znaków-c), a etykieta jest pusta. 31 32 Projekcja zbiorów (1) Przetwarzanie zbiorów data kan2; set kan; keep ilosc_wyp_papierosow efekty_leczenia; 33 34 data kan2; Projekcja zbiorów (2) set kan; drop choroby_wrzody choroby_psychiczne; Projekcja zbiorów (3) data kan2(keep=ilosc_wyp_papierosow efekty_leczenia); set kan; 35 36 6
Efektywna projekcja zbiorów data kan2; set kan(keep=ilosc_wyp_papierosow efekty_leczenia); Obliczenia w Data Step ie data klasa2; set klasa; srednia_ocen=3+sin(wiek); srednia_rach_praw=3+ranuni(0); format srednia_ocen 5.2; format srednia_rach_praw 5.2; 37 38 Warunki i pętle Kolejność instrukcji c.d. data syntetyczny; format x 5.3; format y 5.3; do i=1 to 100; x=ranuni(1234); y=ranuni(5678); if (x*x+y>0.7) then d='t'; else d='n'; output; end; 39 data syntetyczny; drop i; format x 5.3; format y 5.3; do i=1 to 100; x=ranuni(1234); y=ranuni(5678); if (x*x+y>0.7) then d='t'; else d='n'; output; end; 40 _N_ i retain Kolejność instrukcji c.d. data syntetyczny2; data syntetyczny2; set syntetyczny; N=_N_; N=_N_; set syntetyczny; retain srednia_x 0; retain srednia_y 0; srednia_x=((_n_-1)*srednia_x+x)/n; retain srednia_x 0; retain srednia_y 0; srednia_x=((_n_-1)*srednia_x+x)/n; srednia_y=((_n_-1)*srednia_y+y)/n; srednia_y=((_n_-1)*srednia_y+y)/n; 41 42 7
Łączenie zbiorów (unia) Łączenie zbiorów (join,1) data klasa3; set klasa klasa2; Łączy dwa zbiory (konkatenuje). Brakujące kolumny wypełniane są brakującymi wartościami 43 data a; input id a $; 1 a 2 b 3 c data b; input id b $; 1 aa 2 bb 3 cc 4 dd 44 Łączenie zbiorów (join,2) Łączenie zbiorów (join,3) data c; merge a b; by id; Łączy dwa zbiory (join) Brakujące kolumny wypełniane są brakującymi wartościami data a; input id a $; 1 a 2 b 2 b2 3 c data b; input id b $; 1 aa 2 bb 2 bb2 3 cc 4 dd 45 46 Łączenie zbiorów (join,4) data c; merge a b; by id; Łączenie zbiorów nie jest zaimplementowane za pomocą iloczynu kartezjańskiego (każdy z każdym), ale za pomocą liniowego przeglądania Liniowe zamiast n 2 Wymaga posortowanych zbiorów (ale zbiory mogą być utrzymywane w uporządkowaniu) Proc TRANSPOSE 47 48 8
Proc TRANSPOSE (1) proc transpose data=kurs.noty out=kurs.nt; by data; var kurs; id nazwa; Dokonuje transpozycji tablicy w wierszach będą poszczególne dni (by data) w kolumnach będzie wartość zmiennej kurs (var kurs, może być więcej zmiennych) Kolumny będą nazwane na podstawie zmiennej nazwa (id nazwa) 49 Proc TRANSPOSE (2) proc sort data=kurs.noty out=kurs.noty2; by data; Procedura TRANSPOSE wymaga szczególnego wstępnego posortowania danych (efektywność implementacji) dane muszą być posortowane po zmiennej grupującej Uwaga: Każda procedura i data step wykorzystujący grupowanie (tzn. by ) wymaga wstępnego posortowania danych (*). 50 Proc MEANS, Proc FREQ proc means data=kurs.synthetic2; Pozostałe tematy (lista nieobecnych) proc means data=kurs.synthetic2 Q1 MEDIAN Q3 SKEW KURT; proc freq data=kurs.iris; tables petalwid*species / chisq; 51 52 Proc UNIVARIATE proc univariate data=kurs.noty; var kurs; proc univariate data=kurs.noty; histogram kurs; Formaty Pozostałe tematy 4GL Makra i makro zmienne Ustawienia i pliki LAG i DIF Filozofia działania 4GL i makr Indeksowanie, wersjonowanie i zabezpieczanie zbiorów 53 54 9
Zadanie 1 Cel Zadanie 1 Posiadamy dane zebrane z symulatora gry w piłkę nożną (wybrany podzbiór). W bezpośredniej postaci dane te nie nadają się do analiz i predykcji. Należy dokonać transformacji danych, aby uzyskać formę tablicy decyzyjnej. 55 56 Zadanie 1 Wczytanie Należy wczytać zbiór c:\kurs\txt\game_sample2.txt Różni się on od poprzedniego brakiem nagłówka Polecana metoda wczytania: z wykorzystaniem data step a. Metoda zastępcza: konkatenacja plików i wczytanie jak w części I. Zadanie 1 Połączenie Należy połączyć zbiory powstałe przez wczytanie game_sample1_with_header.txt i game_sample2.txt Aby odtworzyć ich poprawną strukturę należy posortować po: TIME_CYCLE PL1_DASH_CNT PL2_DASH_CNT PL3_DASH_CNT PL4_DASH_CNT 57 58 Zadanie 1 Wzbogacenie Należy wyznaczyć średnią wartość energii (stamina) dla każdego gracza. Średnia N = (Średnia N-1 *(N-1) + Wartość bieżaca)/n Wskazówka: Instrukcja retain 59 Zadanie 1 Spłaszczenie Należy spłaszczyć dane, tj. informacja o każdym graczu powinna się znaleźć w tych samych kolumnach jako różne rekordy. W ostatecznym zbiorze powinny znaleźć się kolumny: dist_to_ball, dist_to_goal (środek bramki = (-52.5,0)) x, y avg_stamina, avg_kick_cnt (uśredniany przez liczbę cykli czasowych) strategy(gracz 1 i 2 D, gracz 3 i 4 A ) Wskazówki: instrukcja keep; instrukcja output może być umieszczona wielokrotnie; ** to potęgowanie 60 10