ラベル 関数: MONOTONIC の投稿を表示しています。 すべての投稿を表示
ラベル 関数: MONOTONIC の投稿を表示しています。 すべての投稿を表示

2014年2月19日水曜日

SQLでMONOTONIC関数を使用することについて。




この関数について、すこし紹介(こちら)したことがありますが、
色々調べて注意点をまとめました。




  • まずMONOTONIC関数はSASのリファレンスに載っていない、いわゆる「Undocumented SAS function

  • データステップで使う分にはあまり問題となる事はないですが、SQLプロシジャで使用する際は要注意
    どういう事かというと、、
    データステップだとレコードが並んでる順にデータ処理が行われるけど、

    SQLプロシジャだと再マージやGROUP処理など複雑な処理では、レコードが並んでいる順に処理を行っているわけでは無さそう(内部的な話なので、どのような順で処理を行うのかも分からない)

  • MONOTONIC関数は処理順に連番をふるので、SQLプロシジャで使用すると上記で説明したとおり、意図したものと違う、おかしな順番で番号がふられてしまいます。




MONOTONIC関数の結果値を見ることでSQLプロシジャでの内部処理順を探るヒントになりそうで、それはそれで面白いけど、注意点としておさえておく必要があります。


SASYAMAさんの記事で更なる注意点が見つかりました。
monotonic関数でアイタタタ(データステップ100万回)


2014年1月31日金曜日

行番号を取得する方法




基本的な方法や、あまり知られていない方法をいくつか紹介したいと思います。



*** サンプルデータ ;
data DT1;
input V$;
cards;
a
b
c
d
e
;
*** 行番号を取得 ;
data DT2;
  set DT1;

  * 方法① ;
    OBSN1 + 1;

  * 方法② ;
    OBSN2 = _N_;

  * 方法③ リファレンスに記載のない関数のため非推奨 ;
    OBSN3 = monotonic();
run;



解説

方法①
変数名 + 1」と書くと、前のオブザベーションの変数値を引き継いで、「+1」していってくれる。

方法②
_N_」はSASの自動変数で、データステップの反復回数が格納されています。
データステップは内部の動きとして、オブザベーションの数だけ、データステップをぐるぐるとループ(反復)させています。
ループのたびに1オブザベーションずつ読み込んでいるイメージで、「_N_」はそのループ毎に「+1」した番号が入ります。


方法③ (リファレンスに記載のない関数のため非推奨)
MONOTONIC関数は方法①と同じような挙動をします。



注意事項

方法①~③は厳密には挙動が異なります。
たとえば以下のプログラム実行後、それぞれの方法での結果を見ると異なっています。

data DT3;
  set DT1;
  if V in ("a","c","e");

  * 方法① ;
    OBSN1 + 1;

  * 方法② ;
    OBSN2 = _N_;

  * 方法③ ;
    OBSN3 = monotonic();
run;



これは行番号を振るタイミングが異なるため。

方法①と③:
SET文・WHERE文で読み込まれたオブザベーションに対して番号を振るのですが、、
番号を振る前にサブセット化IF「if  V  in  ("a","c","e")」が実行されていますよね。
このサブセット化IFにより処理が継続されたオブザベーションに対して、番号をふっています。

方法②(自動変数「_N_」):
まずSET文・WHERE文で読み込むオブザベーションに対して、データステップがループ(反復)されますが、自動変数「_N_」は、各反復内でいち早く番号がふられます
番号をふった後で、サブセット化IFにより処理が継続されなかったオブザベーションがあると、番号が連番にならなくなります。


MONOTONIC関数の注意点を追加。

monotonic関数でアイタタタ(データステップ100万回)