ラベル DATAステップビュー の投稿を表示しています。 すべての投稿を表示
ラベル DATAステップビュー の投稿を表示しています。 すべての投稿を表示

2017年11月8日水曜日

DATAステップビューの作成と落とし穴②




「DATAステップビューの作成と落とし穴①」の続き。




落とし穴①


DATAステップビューで参照しているデータセットは、途中で変数を増やしたり減らしたり、属性情報(LENGTHや変数ラベル等)を変更したりするのはNGです。

以下の例では、データセットDT2をSETするという単純なDATAステップビューDSVIEW2を作成しています。

data DT2;
   length X $2.;
   X = "aa";
run;

data DSVIEW2 / view=DSVIEW2;
   set DT2;
run;


ここで、DT2を以下青文字の通り、作り直してみます(変数XのLENGTHを5に増やして"bbbbb"という値を格納)
そして、このDT2を参照しているDATAステップビューDSVIEW2をPROC PRINTで出力してみます。

data DT2;
   length X $5.;
   X = "bbbbb";
run;

proc print data=DSVIEW2 noobs;
run;


あれ?Xには "bbbbb" が格納されているはずなのに、"bb"と出力されていて文字切れを起こしている??

原因として、DATAステップビューには「変数の型やLENGTHといった属性情報」も保存されており、ビューが参照された時にその属性情報が適用されるためです。
(DATAステップビューが作成された時の変数XのLENGTHは「2」だったのでそれが適用された)




落とし穴②

DATAステップビュー参照時にシステムオプションが2回適用されてしまうケースがあります。
例えば、システムオプション「FIRSTOBS=」や「OBS=」がそれにあたります。


まずは、システムオプションの「FIRSTOBS=」・・・ではなくデータセットオプションの「FIRSTOBS=」を使った場合の例。

data DSVIEW3 / view=DSVIEW3;
   set SASHELP.CLASS;
run;

proc print data=DSVIEW3 (firstobs=10) noobs;
run;


データセットオプションで「firstobs=10」としてるので、PROC PRINTでの出力時にオブザベーション=10から処理が開始されています。これは想定通りです。


では次、システムオプションの「FIRSTOBS=」を使った場合。

data DSVIEW3 / view=DSVIEW3;
   set SASHELP.CLASS;
run;

options firstobs=10;
proc print data=DSVIEW3 noobs;
run;
options firstobs=1;





「options firstobs=10;」で以降の処理の開始をオブザベーション=10からにしています。

  • まずはPROC PRINTでDATAステップビューを参照した際、ビューに保存されたプログラムが動くので、その時にオブザベーション=10から処理が行われます
  • そのビューの結果に対してPROC PRINTを実行する際にも、オブザベーション=10から処理が行われます


つまり、FIRSTOBS=システムオプションが2回適用されちゃったわけですね。。
(話それますが、FIRSTOBS=オプションは以下の落とし穴もあって、取り扱い注意)




その他の落とし穴


  • 「DATAステップビューはデータセットと違い実態がない」という事に起因して、一部のデータセットオプションが効かない事もあるので、動作について検証が必要です

  • DATAステップビュー内に記述した「&X」みたいなマクロ変数は展開された上で保存されます


DATAステップビューの作成と落とし穴①




まずはDATAステップビューについて説明して、次の記事で落とし穴を紹介(記事の最後にリンク貼ってます)
ミスを起こしやすい仕様があるので落とし穴の記事も必ず参照下さい!



以下をご覧ください

data DSVIEW / view=DSVIEW;
   set SASHELP.CLASS;
   keep NAME AGE;
run;

proc print data=DSVIEW noobs;
run;


上で作成した DSVIEW は一見データセットに見えますが、「DATAステップビュー」というもので、以下が保存されます。
  • コンパイルしたDATAステップのプログラム
  • 変数の型やLENGTHといった属性情報

このDATAステップビューを開いたり、参照すると、コンパイルしたプログラムが実行されて結果のデータが返ってくる仕組みになっています。


構文

   DATA  ビュー名 / VIEW = ビュー名;
      ~ プログラム ~
   RUN;



ビューの定義を見たい場合は以下のように書きます。

data view=DSVIEW;
   describe;
run;

ログ
NOTE: DATAステップビューWORK.DSVIEWの定義:

data DSVIEW / view=DSVIEW;
   set SASHELP.CLASS;
   keep NAME AGE;
run;




DATAステップビューのメリット


たとえば、以下のようにデータセット MYLIB.DT1 を参照している MYLIB.STAT1 というビューを作ったとします。

data MYLIB.STAT1 / view=MYLIB.STAT1;
   set MYLIB.DT1;
   C = A + B;
run;


そしてこのビューを使って翌日 PROC MEANS を実行したいとします。

proc means data=MYLIB.STAT1;
   var C;
run;


しかし翌日、ビューが参照している MYLIB.DT1 に値の変更が発生したとします。 この場合、再度ビューを作り直す必要はありません。

なぜなら以下のように、

proc means data=MYLIB.STAT1;
   var C;
run;


ビューを参照するだけで、内部で最新の MYLIB.DT1 に対してビューに保存されたデータステップのプログラムが実行され、その結果に対してMEANSが実行されるからです。



またメリットとして、ビューの中身は定義なのでファイルサイズは小さいです。
ただし、プログラム中に何回も同じ中身のビューを参照するような状況では、参照するたびに内部でデータステップのプログラムが実行される事になるので、処理効率が悪くなります。



次回は「落とし穴編」