2015年6月4日木曜日

TRANSPOSEの2回実行テクニック。




データをtransposeで2度漬けすると、1回のtransposeでは実現できないデータを作ることができます。
その一例を紹介したいと思います。


サンプルデータ

data DT1;
    input NO$ SEQ  A$  B$  C$;
    cards;
001 1 XX AA aa
001 2 YY BB cc
002 1 ZZ CC dd
002 2 WW DD bb
;



やりたい事

変数NOの値が同じオブザベーションを、1つのオブザベーションにまとめたい。
まとめるときの変数名は [元の変数名]_[SEQの値] とする。
たとえば、SEQ=1の変数Aは「A_1」、SEQ=2の変数Aは「A_2」という具合です。






📝
前提条件として、転置する変数はすべて同じ型とします。型が異なる場合はこのテクニックは使えません(今回だと変数A, B, Cはすべて文字型)



TRANSPOSE 1回目

proc transpose data=DT1  out=DT2;
    var  A B C;
    by  NO SEQ;
run;


  • まずは、変数NO, SEQ毎に、変数A, B, Cを全て縦に転置。
  • ちなみに、転置対象の変数(今回だとA, B, C)が
    • 全て同じ型で、全て同じフォーマットが割り当てられている場合・・・転置後もそのフォーマットが維持される。
    • 全て同じ型で、各変数に異なるフォーマットが割り当てられている場合・・・転置後はフォーマットが取り除かれる。

 

転置対象の変数にフォーマットが割り当てられている場合は、転置する際に様々な挙動をするのでご注意ください (転置後にデータを確認すること!PROC CONTENTSを使って変数属性も確認してみるとよいです)



TRANSPOSE 2回目

proc transpose data=DT2  out=DT3  delim=_;
    var  COL1;
    by  NO;
    id  _NAME_ SEQ;
    format  SEQ;
run;


  • by NO;」でNOの値ごとに転置。
  • id _NAME_ SEQ;」と「delim=_」の組み合わせで、転置したときの変数名を設定
    • 転置元のデータセットDT2の [_NAME_の値]_[SEQの値] となるようにしてます。
  •  ちなみに「TRANSPOSEのIDステートメント入門」で解説してますが、IDステートメントに指定した変数(今回だと_NAME_, SEQ)にフォーマットが割り当てられている場合は注意。フォーマットをあてたときの値が、転置後の変数名になってしまうからです。
    • 変数_NAME_はtranspose1回目の際にSASが勝手に作った変数で、この変数にはフォーマットは割り当てられない仕様なので問題なし。
    • 変数SEQはこちらで作った変数なので、もしフォーマットを割り当てていた場合は「format SEQ;」と記述して変数SEQのフォーマットを取り除いてから転置することが出来ます。あえてフォーマットをあてたときの値を、転置後の変数名にしたい場合は、この記述は書かなくてもよいので、時と場合によって記述するか判断する。


ちなみに、transpose1回目の際にSASが勝手に「_NAME_」と場合によっては「_LABEL_」という変数を作りますが、これら変数は以下リンク記事にある通り注意が必要です。

難点は2つあって、

ひとつは、転置対象の変数がすべて同じ型であること。
数値型と文字型が混在している場合は、転置する際にSAS側で色々と勝手な変換をしちゃうので、今回のテクニックには向いてません。

もうひとつは、変数達のlengthが、一番大きいやつに合わせられちゃうところですかね。
例えば、各変数のlengthが、以下だった場合、、
A … $5
B … $100
C … $5

転置された変数は、一番lengthの大きい$100に合わせられます。
そのため、ファイル容量もデカくなりがちかも。


メリット・デメリットあるけど、ダイナミックな動きをしてくれるので色んなケースで役に立ってくれます。


0 件のコメント:

コメントを投稿