たとえば今A,B,Cという変数があって、どれか1つ以上でも値が入っていれば、問題なし。
全てが欠損値であるデータをピックアップしたいという状況があったとします。
例えばデータが
data Q1;
IDNO='001';A=.;B=.;C=10;output;
IDNO='002';A=.;B=.;C=.;output;
IDNO='003';A=5;B=.;C=.;output;
run;
こんな感じならwhereで単純に=.をandでつないでもいいし
data A1;
set Q1;
if coalesce(A,B,C)=.;
run;
こんな感じでもいいし、簡単です。
少し頭を使うのは、同じ意味であってもデータ構造が
data Q2;
IDNO='001';ITEM='A';VAL=.;output;
IDNO='001';ITEM='B';VAL=.;output;
IDNO='001';ITEM='C';VAL=10;output;
IDNO='002';ITEM='A';VAL=.;output;
IDNO='002';ITEM='B';VAL=.;output;
IDNO='002';ITEM='C';VAL=.;output;
IDNO='003';ITEM='A';VAL=5;output;
IDNO='003';ITEM='B';VAL=.;output;
IDNO='003';ITEM='C';VAL=.;output;
run;
こういう場合です。
1つのIDにつき項目ごとにオブザベーションが別れています。
問題にすべきはA,B,C全てが欠損である002のIDで、それを特定したいわけですが、
さて、どう書きましょうか?
まず1つとしては
proc transpose data=Q2 out=Q2_(drop=_NAME_);
var VAL;
by IDNO;
id ITEM;
run;
とすれば、最初の問題のデータ構造に転置されるので、そうしてから
同じやり方で片付ける方法です。
縦に解く問題が難しければ、横にすればいいし
横に解く問題が難しければ、縦にすればいいというのはSASの定跡ですね。
まあ、でもこの場合、わざわざデータ構造を変えなくても
例えば、
proc means data=Q2 nway noprint;
class IDNO;
var VAL;
output out=A2(where=(S=.)) sum=S;
run;
このようにすれば、IDごとにAからCの合計をだしてくれるわけですが
sumによる加算結果がnullになるのはどんな時でしょうか?
それは対象全てがnullであったときのみです。その他の場合はnullを除いて足し算してくれます。
すなわちsumがnullであればA,B.Cすべてnullであることに他ならないので
上記のコードでID 002を特定できるわけです。
maxとかでももちろんいいです。
他のアプローチとして、
proc sort data=Q2;
by IDNO VAL;
run;
data A3;
set Q2;
by IDNO VAL;
if last.IDNO and VAL=.;
run;
もアリですね。
ID順、VAL順にソートして、各IDの最後のVALがnullである場合は、そこまでの全てのVALがnullであることと同義ですからね。
0 件のコメント:
コメントを投稿