データを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回目
TRANSPOSE 2回目
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側で色々と勝手な変換をしちゃうので、今回のテクニックには向いてません。
数値型と文字型が混在している場合は、転置する際にSAS側で色々と勝手な変換をしちゃうので、今回のテクニックには向いてません。
もうひとつは、変数達のlengthが、一番大きいやつに合わせられちゃうところですかね。
例えば、各変数のlengthが、以下だった場合、、
A … $5
B … $100
C … $5
転置された変数は、一番lengthの大きい$100に合わせられます。
そのため、ファイル容量もデカくなりがちかも。
メリット・デメリットあるけど、ダイナミックな動きをしてくれるので色んなケースで役に立ってくれます。
0 件のコメント:
コメントを投稿