Markku Suni Factotum emeritus Turun ammattikorkeakoulu DATA-vaiheen ohjelmoijan yleissivistys helposti unohtuvia asioita
Aivan ensimmäiseksi haluan kiittää kuulijoita kuuntelusta Kuten tunnettu poliitikko aloitti Tarkoitukseni on muistuttaa mieleen joitakin DATAvaiheen piirteitä, joiden voisi kuvitella olevan tuttuja, mutta jotka näyttävät helposti unohtuvan käytännössä.
Aivan ensimmäiseksi: selvän koodaamisen merkityksestä Tosin kaikkihan sen tietävät Sisennetään ohjelma sopivasti se lisää selkeyttä: data tulos ( keep = yksi pieni tieto ) set alku ( keep = talleta yksi tieto ); infile sasin1; input @1 yksko $char5. /* yksikkökoodi */ @12 pieni $char5. /* pientoimituskoodi */ ; if yksko = yksi then... Ohops! Sattuipa nolosti!
Selvän koodaamisen merkityksestä data tulos ( keep = yksi pieni tieto ) set alku ( keep = talleta yksi tieto ); infile sasin1; input @1 yksko $char5. /* yksikkökoodi */ @12 pieni $char5. /* pientoimituskoodi */ ; if yksko = yksi then... Ohops! Sattuipa nolosti! Puuttuu puolipiste data-lauseen lopusta
Selvän koodaamisen merkityksestä DATA tulos ( keep = yksi pieni tieto ) ; SET alku ( keep = talleta yksi tieto end = loppuiset ); infile sasin1 end = loppuifile ; if not loppuifile input @1 yksko $char5. /* yksikkökoodi */ @12 pieni $char5. /* pientoimituskoodi */ ; if yksko = yksi then... Ohops! Sattuipa nolosti! Ajatus oli lukea SAS-tiedostoa ja peräkkäistiedostoa samaan tahtiin.. Entäs, jos tiedostoissa on eri määrä havaintoja?
Ellei koodata selkeästi, On vaikeaa todeta Koodin kuntoa. Auttaisiko BUGOMETER?
Palautetaanpa mieleen, milloin ja miten output tapahtuu Tiedoston avaa lause INFILE tai SET Lukeminen tapahtuu lauseella INPUT tai SET - näiden lauseiden kohdalla Tulostus tapahtuu lauseella PUT tai OUTPUT Lukeminen loppuu silloin, kun lukulause ei onnistu ( ts. tuottaa EOF-merkin ) - ei viimeisen tietueen kohdalla
Entäs, jos emme tiedä, montako tietuetta on? DATA molemmat (KEEP =... ) INFILE inputti1 END = ended1 ; IF ended1 = 0 THEN INPUT ; INFILE inputti2 END = ended2 ; IF ended2 = 0 THEN INPUT ; RUN; /* hoidetaan kaikenlaista */
Entäs, jos emme tiedä, montako tietuetta on? DATA molemmat (KEEP =... ) INFILE inputti1 END = ended1 ; IF ended1 = 0 THEN INPUT ; IF ended2 = 0 THEN SET inputti2 ( END = ended2 ) ; RUN; /* hoidetaan kaikenlaista */
Tiedostojen hyödyllisiä optioita DATA new ( KEEP = custno /* asiakasnumero, num */ object /* vakuutuskohteen koodi */ income /* maksutulo */ outcome /* kustannukset yht. */ ); SET old( DROP = policy term version RENAME = ( payment = income ) RENAME = ( claimspay = outcome ) WHERE = ( year = 2009 )); IF income > 10 THEN...... RUN;
CAUTION DO NOT DISTURB Professional SAS program at work
Monipuolinen DO DO END on lohko, joka suoritetaan kerralla DO laskuri = 1 TO 10;... END; DO laskuri = alaraja TO ylaraja BY askel;... END; IF jotain THEN DO laskenta = 10 TO 0 BY -1 ;.... END; Tämähän on tuttua kaikki muistavat.
Monipuolinen DO DO END toimii myös listan avulla DO fibonacci = 1, 2, 3, 5, 8, 13, 21, 44, 63 ;... END; DO coding = XA, XB, XQ, XZ ;... END; Tämänkin ehkä muistamme.
Monipuolinen DO Mutta entäs nämä: DO UNTIL (( tax_change < 0 ) AND ( salary_change > 0)); DO UNTIL ( count >= 100 ); DO UNTIL ( cows_come_home ) ; DO WHILE (( tax_change >= 0 ) OR ( salary_change <= 0)); DO WHILE ( count < 100 ); DO WHILE ( NOT( file_loppui )) ;
Monipuolinen DO Puhumattakaan tästä: DO from = here TO eternity UNTIL ( war_begins ); DO days = 1 TO 1000 UNTIL ( correct > 10 ); DO counter = 1 TO 100 WHILE ( errorcount < 10 ); DO WHILE ( TRUE );... IF XX THEN LEAVE;.. END;
Procedure PRINTTO vanha, mutta toimiva filename routed 'output-file'; proc printto print = routed new; run; proc freq data=test; tables x*y / chisq; run; data probtest( keep = df chisq prob ); infile routed; input word1 $ @; if word1='chi-squa' then do; input df chisq prob; output; end; run;
SAS-tiedostojen yhdistäminen: BY-lauseella Öhman Åke
Muuten, muistatkos tätä? Funktion argumenttina voi toimia muuttuja tai lauseke: Jonkun edellisen kuun alku niinmonta kuuta sitten: ajopvm = today(); edkuu = month( ajopvm ) - niinmonta; edalku = MDY( edkuu + ( edkuu <= 0 )*12, 1, year( ajopvm ) - ( edkuu <= 0 )); Siis: MDY( kuukausi, paiva, vuosi )
Muuten, muistatkos tätä? Funktio INDEX etsii jonkin pituisia merkkijonoja: length laji $ 1; SET tiedot; IF ( index( ABC, laji ) ) THEN DO; IF ( laji IN ( A, B, C ) THEN DO; IF ( laji = A laji = B laji = C ) THEN DO; Mitä eroa on noissa kolmessa IF-lauseessa?
DATAvaiheen alussa SAS alustaa kaikki muuttujat puuttuviksi, paitsi jos muuttuja on mainittu RETAIN-lauseessa on olemassa globaalinen RETAIN-lause muuttuja esiintyy summaavan lauseen vasemmalla puolella summing statement muuttuja luetaan SAS-tiedostosta muuttujaa käytetään I/O-lauseen optiossa Muuttujien alustus
Muuttujien alustus DATAvaiheen alussa SAS alustaa kaikki muuttujat puuttuviksi, paitsi jos muuttuja on vektori (ARRAY) ja ARRAY-lause antaa alkuarvot vektorissa on tilapäisiä muuttujia vektoria käytetään summaavassa lauseessa vektori mainitaan RETAIN-lauseessa
FORMATin monta puolta PROC FORMAT value tili low - <0 = ylitys other = _same_; PROC FORMAT value ikary 0 12 = lapsi 12-19 = teini 20-60 = työik 60 HIGH = vanha ; ikaluokka = PUT( ika, ikary5. ); IF ( PUT( ika, ikary5. ) = lapsi THEN... IF ( PUT( saldo, tili. ) = ylitys THEN...
FORMATIN SOVELLUS FORMAT sopii moneen, esim. havaintoarvojen luokitteluun PROC FORMAT; value painot low - 40 = 1 41-60 = 2 61-80 = 3 81 - HIGH = 4; RUN; DATA neljas; length painolk $ 8; SET kokeilu; painolk = Luokka!! PUT( paino, painot. ); painory = INPUT( PUT( paino, painot3. ), 3. ); RUN;
IKIVANHA PROSEDUURI Data kokeilu; INPUT akt hinta alku loppu CARDS; 1 15 2 8 Alustan valaminen 2 8 5 12 Rakennuslupa 3 11 2 12 Materiaalihankinta 4 10 8 15 Alustan verhoilu 5 22 15 22 Seinän tekeminen 6 5 24 25 Projektin päättäminen ; PROC timeplot data = kokeilu;
PROC timeplot data = kokeilu; PLOT alku loppu / overlay hiloc ref = 12; ID akt hinta; LABEL hinta = MEur akt = aktivi- teetti ; TITLE Projektin aikataulu ; FORMAT akt hinta alku loppu 4. ; RUN; Ja tulokseksi tulee IKIVANHA PROSEDUURI
IKIVANHA PROSEDUURI Projektin aikataulu aktivi- MEur ALKU LOPPU min max teetti 2 25 *---------------------------* 1 15 2 8 A--------L 2 8 5 12 A------------L 3 11 2 13 A------------------L 4 10 8 15 A------------L 5 8 12 14 A L 6 5 24 25 AL *---------------------------*
Muistutus: automaattimuuttuja _INFILE_ pitää sisällään sen, mitä on syötöstä luettu: DATA _NULL_; INFILE FILE INPUT ja OUTPUT sisaan; ulos; INPUT $1 koodi 2.; IF koodi = 12 THEN PUT _INFILE_; RUN; Tai:... IF koodi = 12 THEN PUT Valitut: @10 _INFILE_;
Miten tuo lasketaan? Helposti: EALin_kanssa = 12* (EALin_kanssa - ilman_ealia) Vastaavasti: A antaa 78% enemmän säihkettä kuin B. enemman = a_saihke b_saihke); enemman_kertaa = (a b) / b ; enemman_pros = (( a b ) / b ) * 100; Prosenttilasku on vaikeaa jopa poliitikoille.
This is the end The Doors