Casser Notes

SASメインで使っていたエンジニアのステップアップの記録

Advenceを取ってもwhereとサブセットIFの違いを間違えた話

今回はSASの話

 

とある案件でカラムの値ごとにファイルを出力したいという話があって、まあサブセットIFで分岐して適当にfileステートメントで出力したらいいだろうと考えてたけど、勉強不足から落とし穴にハマった

 

1 FILEステートメントは0オブザベーションでもファイルを生成する

まずここで悩んだ

結論としてはcall symput(count,_N_)で取得した件数を格納した&count マクロ変数を%symexist()を使って存在確認の上0ならfdeleteで削除するということにした

data _null_;
set dummy end = eof;
where type = "&typeval.";
file myfile dsd;
put type name;

If eof then
call symput("count",_N_);
run;

 

%if %symexist(cnt) = 0 %then
%do;
%put %sysfunc(fdelete(myfile));
%end;

※ コードは端折ってます

 

2 サブセット化IFステートメントとWhereステートメントの違い

SAS Certified Advanced Programerでやっていながら、ここの違いを勘違いしていた

 

上のプログラムは&typeval を 

%macname(typea);

%macname(typeb);

みたく別の値を与えてwhereで絞ってから出力&0件なら消すという処理をしてるけど、

最初はいつものクセでサブセット化IFでやろうとしていた

 

…が意図した結果にならず、結論としてはWhereとサブセット化IFのオブザベーション選択方法の違いにあった

 

すっごい初歩的な話だけど、よく理解できてなかった

●オブザベーション選択のタイミング オブザベーションを読み込む場合、PDV(プログラムデータベクトル)に値が読み込まれます。
WHEREステートメントはPDVに読み込まれる前に作用します。一方サブセット化IFステートメントはPDVに読み込まれた後に作用します。 

サブセット化IFステートメントとWHEREステートメントの違い - SAS Support Communities

 

そう、Whereの場合は例えば

type name

a taro

a jiro

b saburo

となっていた場合にwhere type = それぞれのtypeで絞った場合の_N_が

type _N_

a 2

b 1

となってくれるけど、if type=それぞれのtypeで絞った場合は

type _N_
a 欠損値

b 3

となる

 

最初はよくわからなかったけど、

whereは絞った状態でPDVに持ってきてくれるからtype a,bとも件数絞った状態で持ってきてくれて思った通りの_N_が取れる

 

しかし、ifの場合はPDVに持ってきてから弾くので、type bは3オブザベーション目なので3になる

type aはよく分かんないけど、3オブザベーション目が読み込まれた時にこれはいらねえってSASが判断して_N_をリセットしてるんだろうか

 

そもそも、サブセット化IFをよく使うようにしたのも、そっちの方が性能がいいから…としてた気がするけど、それも勘違いだったのかな…

 

まだ調べてないけど、なんかAdvanceの勉強した時の資料に書いてあった気がするʕ •́؈•̀ ₎

 

今のところはこんな感じだけど、とりあえずは目的を達成できたので良し

 

Advanceを取っても取るだけじゃダメだという教訓になった