条件ごとにファイル出力&ヒットするオブザベーションがない場合はファイルを削除する
今回は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_をリセットしてるんだろうか
まだ調べてないけど、なんかAdvanceの勉強した時の資料に書いてあった気がするʕ •́؈•̀ ₎
今のところはこんな感じだけど、とりあえずは目的を達成できたので良し
Advanceを取っても取るだけじゃダメだという教訓になった