SAS Slovakia Newsletter / Tipy a triky

Vlastné funkcie v našich SAS programoch

Tiež vás pri písaní programov v SASe napadlo, či si okrem štandardných funkcií (a subrutín), ktoré SAS ponúka, nemôžete definovať aj vlastné? Presne tak, ako v tradičných programovacích jazykoch.  Áno, existujú predsa makrá, ktoré vlastné funkcie čiastočne nahrádzajú. No majú aj svoje nevýhody. V tomto článku ukážeme, ako napísať vlastnú funkciu či subrutinu, aké to má výhody oproti makrám a ukážeme si široké možnosti použitia týchto funkcií vo verzii SAS 9.2.

Keď nás makro hnevá

Predstavme si, že potrebujeme v niekoľkých data stepoch zavolať funkciu, ktorá skontroluje správnosť slovenského čísla bankového účtu. Keďže chceme napísať viacnásobne použiteľný kód, redukovať údržbu kódu a podobne, napíšeme takéto makro:

Pozrime sa, čo sa však stane, keď ho použijeme v tele data stepu, ba navyše v tele cyklu data stepu:

Tento kód radšej ani nespúšťajte. Istotne nevykoná to, čo by sa na prvý pohľad mohlo zdať. Problém je v použití premennej i v tele cyklu volajúceho data stepu, ako aj vnútri makra. Vznikla veľmi neprehľadná situácia.
Pri použití makra vnútri data stepu treba myslieť na to, aby nekolidovali názvy premenných, aby sa pomocné premenné nezachovávali, čo je zas problém, ak vonkajší data step použil jeden keep statement atď. V krátkosti, makrá môžu vniesť namiesto transparentnosti problémy.  Ba čo viac, makrom sa nedá priamočiaro simulovať rekurzívna funkcia.

Definícia vlastnej funkcie

Na pomoc prichádzajú tzv. user defined funkcie. Vlastnú funkciu definujeme, ako vidieť z nasledujúceho príkladu, pomocou proc fcmp.

Použitie vlastnej funkcie

V tomto prípade bola zadefinovaná funkcia CheckAccNr, ktorá bola skompilovaná a zapísaná do katalógu bankfuncs v knižnici sasuser. Ak ju chceme použiť, musíme definovať, že SAS má hľadať funkcie (aj) v tomto katalógu:

Následné použitie v data stepe je úplne priamočiare:

Definovanie vlastnej funkcie bolo možné aj v skorších verziách SAS, než je 9.2. Avšak použiť túto funkciu nebolo možné vnútri data stepu, ani v rámci proc sql. Verzia SAS 9.2 prináša možnosť volania týchto funkcií z data stepu a z proc sql. Nasleduje príklad volania vlastnej funkcie checkAccNr z SQL dotazu.

Načo teda vlastne možnosť definovania vlastnej funkcie existovala? Tieto funkcie bolo a taktiež je možné použiť v rámci modelovania časových radov (napr. Proc model z SAS/ETS) alebo pri nelineárnej optimalizácii (napr. Proc NLP v SAS/OR). Nasledujúci príklad SAS programu nájde optimálne umiestnenie skladu voči niekoľkým odbytovým miestam s cieľom minimalizovať súčet vzdialeností pri obmedzení, že tento sklad je v istej minimálnej vzdialenosti od nebezpečného skladu chemického odpadu.

Formálnejšie povedané, rieši úlohu:

min∑i(x - xmi )2 + (y - ymi )2

Pri obmedzení

(x - xs)2 + (y - ys)2 >= R

xm, ym, xs, ys, R sú dané konštanty – súradnice odbytových miest, nebezpečnej skládky a R je minimálna vzdialenosť od skládky.

Ďalšie užitočné informácie

Ak vás možnosť definovanie vlastných subrutín a funkcií zaujala a chcete vedieť viac, prečítajte si napríklad nasledujúci dokument:
http://support.sas.com/rnd/base/datastep/whats-new-base-sas92.pdf 
Úplne brutálny spôsob použitia vlastnej funkcie, ktorá volá vlastné SAS makro sa dá nájsť  tu:
http://www.sasanalysis.com/2011/02/macro-powered-function-finds-auc.html.

Róbert Macho