TRANSPOSE→CATX関数のコンボで縦持ちのデータを1行1変数に指定文字で連結してまとめてみる

CATX関数の使い勝手がよいという話題です。

たとえば以下のようなデータがあったとします。

data Q1;
length ID $10.;
ID='AAA';NO=2;ITEM='ろ';output;
ID='AAA';NO=1;ITEM='い';output;
ID='AAA';NO=3;ITEM='';  output;
ID='AAA';NO=4;ITEM='は';output;
ID='BBB';NO=1;ITEM='A'; output;
ID='BBB';NO=5;ITEM='B'; output;
run;



これをIDごとに、出現するITEMの内容を、NO順に「、」で連結して
ALLITEMという変数にいれるという問題があったとします。
求めたい結果は以下です。


なんか面倒そうだと感じますが、楽勝です。

まず、IDとNOでソートした後、IDをbyで固定してtransposeします。
このときIDステートメント(すみません、変数とまぎらわしいですね)でNOを指定します。


proc sort data=Q1;
 by ID;
run;

proc transpose data=Q1 out=Q2(drop=_NAME_) prefix=ITEM_;
 var ITEM;
 by ID;
 id NO;
run;

すると



のデータセットが得られます。
後はこれを順番に「、」で繋ぎたいのですが、nullの場合は飛ばしたいわけです。
空白が間にはいるのも嫌なので、う~んどうしよう、IFいっぱい書かなきゃいけないかと思いきや

data A;
 set Q2;
  ALLITEM=catx('、',of ITEM_:);
 keep ID ALLITEM;

run;

これで、終わりです。
catx関数は指定した区切り文字で、null以外の値を、前後の空白を除去した上で連結してくれるという、凄く気のきいた関数です。
もちろん
  ALLITEM=catx('、',ITEM_1,ITEM_2,ITEM_3,ITEM_4,ITEM_5);
とかいていいのですが、そうすると元データが増えてNO「6」ができたら
コードを修正する必要がでてしまいます。

TRANSPOSEプロシジャのprefix=は接頭語を指定できるので(suffix=は接尾語)
ここをうまく使えば、NOがどんな数字だろうと、転置後の変数は「ITEM_」から始まります。
そこで of とコロンモディファイアで、配列を使うまでもなくターゲットの変数を全て捕まえることが
できます。

CAT やCATSなど、微妙に違うことをしてくれる関数もあるので調べてみるといいと思います





0 件のコメント:

コメントを投稿