Úkol 12 Přemysl Bejda 22. března 2008 1 Něco málo k SAS SAS slouží pro statistiky, jeho využití není příliš flexibilní, protože v něm nelze psát vlastní procedury. Komentáře v programu píšeme pomocí symbolu /** text **/. Jednotlivé příkazy se oddělují středníky stejně jako v C. Na konci každé procedury musí být příkaz run. Navíc tam může být i quit (zavření některých oken). 2 Načtení dat S daty se zachází s použitím procedury data. Načtou se do pracovního adresáře work a budou se jmenovat rodina, jednotlivé sloupečky budou mít názvy age, sex, num, rel1, sex1, vek1, cas1,... Na samotné načtení dat (po řádcích) se použije příkaz cards nebo ekvivalentně datalines. Pak se postupně po řádcích zadávají data oddělovaná mezerami, na konci řádků se zmáčkne enter, na konci dat středník). Standardní znak pro chybějící pozorování je tečka. data work.rodina input age sex num rel1 sex1 vek1 cas1 rel2 sex2 vek2 cas2 rel3 sex3 vek3 cas3 rel4 sex4 vek4 cas4 rel5 sex5 vek5 cas5 cards /** datalines **/ 22 1 2 2 1 52 60 2 2 52 20............ 23 1 2 2 1 53 90 2 2 60 60............ 22 2 4 2 1 50 30 2 2 52 30 1 1 20 15 1 2 22 45.... 22 2 2 2 2 57 60 2 1 51 60............ 22 2 2 2 1 50 40 1 1 18 58............ 23 1 3 1 1 24 20 2 1 48 40 2 2 53 20........ 28 2 2 1 1 24 10 2 1 60 10............ 22 1 4 1 2 23 5 2 1 49 20 2 2 63 20 3 1 87 30.... 23 2 3 1 2 25 115 2 1 50 35 2 2 61 50........ 22 1 3 2 1 51 50 2 2 52 40 1 2 28 40........ 24 2 2 2 1 49 100 1 2 22 30............ 24 1 3 1 1 17 10 2 1 46 15 4 2 45 5........ 1
22 1 3 1 1 16 180 2 1 44 100 2 2 45 100........ 22 1 2 2 1 49 120 1 2 16 60............ 23 1 3 2 2 53 60 2 1 50 30 1 2 25 60........ 23 1 4 1 1 20 120 2 2 47 15 2 1 47 75 3 1 77 45.... 23 1 2 2 1 62 100 2 2 63 60............ 23 1 4 1 1 23 80 1 1 25 180 2 1 53 60 2 2 53 80.... 23 2 10 2 2 46 15 2 1 46 15 1 1 21 5 1 1 18 5 1 1 17 5 22 1 4 2 2 52 10 2 1 51 10 1 1 23 30........ 22 2 3 2 1 48 10 1 2 25 25 1 1 24 1........ run 2.1 Chybějící pozorování Chybějící pozorování nahradíme nulami. První možnost, jak to udělat je následující: Pomocí příkazu set (v proceduře data) přepíšeme tečky ve všech sloupcích za nuly. Vzniklá (upravená) data pojmenujeme rodinac. data work.rodinac set work.rodina if rel2=. then rel2=0 if rel3=. then rel3=0 if rel4=. then rel4=0 if rel5=. then rel5=0 if sex2=. then sex2=0 if sex3=. then sex3=0 if sex4=. then sex4=0 if sex5=. then sex5=0 if vek2=. then vek2=0 if vek3=. then vek3=0 if vek4=. then vek4=0 if vek5=. then vek5=0 if cas2=. then cas2=0 if cas3=. then cas3=0 if cas4=. then cas4=0 if cas5=. then cas5=0 run Data vypíšeme pomocí procedury print. proc print data=rodinac run quit Druhá možnost je data znovu načíst s tím, že místo teček mám nuly. Tentokrát je pojmenujeme rodinaf. 2
data work.rodinaf input age sex num rel1 sex1 vek1 cas1 rel2 sex2 vek2 cas2 rel3 sex3 vek3 cas3 rel4 sex4 vek4 cas4 rel5 sex5 vek5 cas5 cards 22 1 2 2 1 52 60 2 2 52 20 0 0 0 0 0 0 0 0 0 0 0 0 23 1 2 2 1 53 90 2 2 60 60 0 0 0 0 0 0 0 0 0 0 0 0 22 2 4 2 1 50 30 2 2 52 30 1 1 20 15 1 2 22 45 0 0 0 0 22 2 2 2 2 57 60 2 1 51 60 0 0 0 0 0 0 0 0 0 0 0 0 22 2 2 2 1 50 40 1 1 18 58 0 0 0 0 0 0 0 0 0 0 0 0 23 1 3 1 1 24 20 2 1 48 40 2 2 53 20 0 0 0 0 0 0 0 0 28 2 2 1 1 24 10 2 1 60 10 0 0 0 0 0 0 0 0 0 0 0 0 22 1 4 1 2 23 5 2 1 49 20 2 2 63 20 3 1 87 30 0 0 0 0 23 2 3 1 2 25 115 2 1 50 35 2 2 61 50 0 0 0 0 0 0 0 0 22 1 3 2 1 51 50 2 2 52 40 1 2 28 40 0 0 0 0 0 0 0 0 24 2 2 2 1 49 100 1 2 22 30 0 0 0 0 0 0 0 0 0 0 0 0 24 1 3 1 1 17 10 2 1 46 15 4 2 45 5 0 0 0 0 0 0 0 0 22 1 3 1 1 16 180 2 1 44 100 2 2 45 100 0 0 0 0 0 0 0 0 22 1 2 2 1 49 120 1 2 16 60 0 0 0 0 0 0 0 0 0 0 0 0 23 1 3 2 2 53 60 2 1 50 30 1 2 25 60 0 0 0 0 0 0 0 0 23 1 4 1 1 20 120 2 2 47 15 2 1 47 75 3 1 77 45 0 0 0 0 23 1 2 2 1 62 100 2 2 63 60 0 0 0 0 0 0 0 0 0 0 0 0 23 1 4 1 1 23 80 1 1 25 180 2 1 53 60 2 2 53 80 0 0 0 0 23 2 10 2 2 46 15 2 1 46 15 1 1 21 5 1 1 18 5 1 1 17 5 22 1 4 2 2 52 10 2 1 51 10 1 1 23 30 0 0 0 0 0 0 0 0 22 2 3 2 1 48 10 1 2 25 25 1 1 24 1 0 0 0 0 0 0 0 0 run Příkaz pro vypsání dat vypadá následovně: proc print data=rodinaf run quit 3 Rozdíl věku rodičů a počet dětí Dál chceme vytvořit data, která navíc budou obsahovat sloupeček s veličinou udávající rozdíl věků rodičů a sloupeček s počtem dětí v rodině. Vytvoříme tedy nová data nazvaná rodinaf2. Vyjdu z dat rodinaf. Pokud jsou v řádku oba rodiče, do proměnné FminusM se přiřadí rozdíl věku otce a matky F je father a M je mother. Dál se spočte počet dětí (počet sourozenců plus jedna). A navíc se vytvoří sloupeček FminusMsq, ve kterém bude druhá mocnina rozdílu věku rodičů. data work.rodinaf2 set work.rodinaf 3
if (((rel1=2 and sex1=1) or (rel2=2 and sex2=1) or (rel3=2 and sex3=1) or (rel4=2 and sex4=1) or (rel5=2 and sex5=1)) and ((rel1=2 and sex1=2) or (rel2=2 and sex2=2) or (rel3=2 and sex3=2) or (rel4=2 and sex4=2) or (rel5=2 and sex5=2))) FminusM = (rel1-1)*(rel1-3)*(rel1-4)*(sex1-1.5)*vek1 +(rel2-1)*(rel2-3)*(rel2-4)*(sex2-1.5)*vek2 +(rel3-1)*(rel3-3)*(rel3-4)*(sex3-1.5)*vek3 +(rel4-1)*(rel4-3)*(rel4-4)*(sex4-1.5)*vek4 +(rel5-1)*(rel5-3)*(rel5-4)*(sex5-1.5)*vek5 deti = 1+rel1*max(0,2-rel1)+rel2*max(0,2-rel2) +rel3*max(0,2-rel3)+rel4*max(0,2-rel4)+rel5*max(0,2-rel5) FminusMsq = FminusM*FminusM run Tady se dost využívá struktury dat. Např. to (rel1-1)*(rel1-3)*(rel1-4) způsobí, že pokud pozorování není rodič nic se neděje. Opět zobrazíme nová data. proc print data=rodinaf2 run quit 4 Pojmenování faktorů Nejdřív se udělá procedura s popisem hodnot. V2f bude znamenat, že jednička je žena a dvojka muž. V4f bude říkat, že jednička je sourozenec, dvojka rodič, trojka prarodič a čtyřka něco jiného. proc format value V2f 1="zena" 2="muz" value V4f 1="sourozenec" 2="rodic" 3="prarodic" 4="ostatni" run Pak se data rodinaf2 změní tak, že sloupečky obsahující pohlaví budou nabývat hodnot V2f (zena a muz), sloupečky týkající se rodinného vztahu hodnot V4f (sourozenec, rodic, prarodic a ostatni). Nakonec, když data znovu zobrazíme, vidíme, že příslušná čísla se mi nahradila slovy. 4
proc datasets lib=work nolist modify rodinaf2 format sex V2f. format rel1 V4f. format sex1 V2f. format rel2 V4f. format sex2 V2f. format rel3 V4f. format sex3 V2f. format rel4 V4f. format sex4 V2f. format rel5 V4f. format sex5 V2f. run proc print data=rodinaf2 run quit Aby ve výstupních souborech byly jednotlivé proměnné pěkně pojmenované, můžeme ještě jednotlivé sloupečky nějak označit. proc datasets lib=work nolist modify rodinaf2 label age="age" label sex="sex" label num="members" label rel1="relation 1" label sex1="sex 1" label vek1="age 1" label cas1="time 1" label rel2="relation 2" label sex2="sex 2" label vek2="age 2" label cas2="time 2" label rel3="relation 3" label sex3="sex 3" label vek3="age 3" label cas3="time 3" label rel4="relation 4" label sex4="sex 4" label vek4="age 4" label cas4="time 4" label rel5="relation 5" label sex5="sex 5" label vek5="age 5" label cas5="time 5" label deti="number of Children" 5
label FminusM="Age Difference (Father - Mother)" label FminusMsq="Squared Age Difference of Parents" run 5 Závislost počtu členů rodiny na věku na pohlaví Tabulky popisných statistik se zobrazí příkazem freq. To lze udělat jak pro data rodinaf2 tak i pro data rodinaf. (V prvním případě mám jen ty řádky, kde jsou oba rodiče, ve druhém mám všechna data.) proc freq data=rodinaf2 tables age sex num run proc freq data=rodinaf tables age sex num run Graficky znázorníme závislost počtu členů rodiny na pohlaví tak, že data nejdřív srovnáme podle pohlaví (aby byly řádky pro každé pohlaví pohromadě) a pak pomocí procedury univariate a příkazu plot vytisknu boxploty. Děláme to pro všechna data (ne jen pro rodiny s oběma rodiči). proc sort data=rodinaf by sex run proc univariate data=rodinaf plot var num by sex run Stejně se znázorní závislost počtu členů rodiny na věku. proc sort data=rodinaf2 by age run proc univariate plot data=rodinaf2 var num by age run 6
6 Závislost proměnných věkový rozdíl rodičů a počet dětí Graf počtu dětí v závislosti na věkovém rozdílu rodičů se udělá pomocí procedury gplot. proc gplot data=rodinaf2 plot deti*fminusm run Lineární regresní model se dá vytvořit pomocí procedury gplot. Příkazem model se model sestrojí, odhadnou se parametry a pomocí plot se vytisknou původní hodnoty i jimi proložená přímka. proc reg data=rodinaf2 model deti = FminusM plot deti*fminusm run quit Pokud chceme porovnat lineární a kvadratickou regresi, použijeme poslední sloupeček FminusMsq v datech rodinaf2, ve kterém mám druhou mocninu rozdílu věku rodičů. proc reg data=rodinaf2 Linear: model deti = FminusM Quadratic: model deti = FminusM FminusMsq run quit 7