2010年3月30日火曜日

SAS9.2から追加になったFCMPプロシジャを使ってみる

SAS version 9.2からユーザー独自の関数を作成できるプロシジャ
FCMPプロシジャが新しく加わりました。

簡単な構文ですが以下に解説します。
今回は誕生日と現在日付(共にSAS日付値)を引数に与えると
年齢「○○歳」と結果を返す関数を作成してみます。

/*--------- 関数作成編 ---------*/
libname sasfunc "e:\sasfunc";

proc fcmp outlib=sasfunc.functions.test;

function getAge(today, birthday) $;
_tmp1 = intck('YEAR', birthday, today);
_tmp2 = (month(birthday)*100 + day(birthday)) - (month(today)*100 + day(today));
if _tmp2 > 0 then age = _tmp1 -1;
else age = _tmp1;
return(put(age, best.)||'歳');
endsub;

run;
/*----------------------------------*/

▼まず作成した関数を保存するフォルダにLIBRARY参照名を定義します

▼FCMPプロシジャを使ってユーザー定義関数を作成します
・outlib=オプションで<ライブラリ参照名>.<データセット名>.<パッケージ>の順に指定します
・functionステートメントに 関数名(例ではgetAge)、引数を指定します。
戻り値が文字値の場合は最後に「$」を指定します。
・通常のデータステップと同じ文法で変数を作成します。
・return()ステートメントで()内に返す戻り値を指定します。
・endsubステートメントで関数定義を終了します。

▼実行すると以下のようなログが出力され、関数が登録されます。

NOTE: Function getAge saved to sasfunc.functions.test.
NOTE: PROCEDURE FCMP 処理 (合計処理時間):
処理時間 2.00 秒
CPU 時間 0.14 秒


(登録は指定したライブラリにデータセットとして登録されます。)

次に作成したユーザー定義関数を使用してみましょう。

/*--------- 関数使用編 ---------*/
options cmplib = sasfunc.functions;

data _null_;

today = '2may2010'd;
birthday= '2may1977'd;

age = getAge(today, birthday);

put age=;
run;

/*----------------------------------*/

▼options cmplib = <ライブラリ参照名>.<データセット名>
登録した関数が保存されているライブラリ参照名とデータセット名を指定します。

▼あとはDATAステップ内で従来のSAS関数と同様に使用するだけです。
他にもwhereステートメント内や、いくつかのプロシジャ内でも使えるようです。
実行ログは以下のようになりました。

24 options cmplib = sasfunc.functions;
25 data _null_;
26
27 today = '2may2010'd;
28 birthday= '2may1977'd;
29
30 age = getAge(today, birthday);
31
32 put age=;
33 run;


age=33歳
NOTE: DATA ステートメント 処理 (合計処理時間):
処理時間 0.62 秒
CPU 時間 0.03 秒


以上、簡単なFCMPプロシジャの使い方でした。

ではFCMPプロシジャとユーザー定義関数にはどのような利点があるでしょうか?
米SASサポートサイトのFCMPプロシジャのoverviewに次の文章があります

This feature enables programmers to more easily read, write, and maintain complex code with independent and reusable subroutines.
You can reuse the PROC FCMP routines in any DATA step or SAS procedure that has access to their storage location.

まとめると
・独立した再利用可能な関数によって複雑なコードの読み書き、保守がやりやすくなる。
・定義データにアクセスできればどこからでもDATAステップ、やプロシジャで再利用できる。

今まででもマクロプログラムでこれに近いことができますが
FCMPプロシジャを使えばより独立性と再利用性が高まるといった感じでしょうか。
とはいえ従来と毛色の違う新しい機能ですし、開発プロジェクトに導入するには
コーディングルールや、ドキュメントの書き方、定義関数の管理に至るまで
考えなくてはいけない事は多そうです。
従来マクロとの性質の違い、長所短所を理解した上で適用すれば
便利に使えて開発効率が上がる場面もあるのではないでしょうか。

おわり


投稿者:@miya_NI


0 件のコメント:

コメントを投稿

ネイチャーインサイト サイトリニューアル&NIBLOGの引っ越し

ご連絡が遅くなりましたが、 ネイチャーインサイトの際とがリニューアルしました。 https://www.n-insight.co.jp/ それに伴い、NIBLOGも引っ越しすることになりました。 https://www.n-insight.co.jp/niblog/ ...