data Q1;
ID="001";VISITN=1;A=1;B=2;C=3;output;
ID="001";VISITN=2;A=3;B=4;C=5;output;
ID="002";VISITN=1;A=6;B=7;C=8;output;
ID="002";VISITN=2;A=9;B=0;C=1;output;
run;
以下の全転置データセットを作りたい場合
proc transpose data=Q1 out=_A prefix=A_;
var A;
id VISITN;
by ID;
run;
proc transpose data=Q1 out=_B prefix=B_;
var B;
id VISITN;
by ID;
run;
proc transpose data=Q1 out=_C prefix=C_;
var C;
id VISITN;
by ID;
run;
data RES1;
merge _A _B _C;
by ID;
drop _NAME_;
run;
と書いたりします。
もちろん、これで正解です。
変数が10個なら10回transposeかければいいんですが、ちょっと工夫を考えてみます
例えば、今回の場合だと「ID」 と「パラメータ」と「値」で構成される縦積み構造にしてから転置すれば1回の転置でスムーズに結果がだせます。
つまり
data _Q1;
set Q1;
array ch A--C;
do over ch;
VNAME =vname(ch);
VAL=ch;
output;
end;
keep ID VNAME VISITN VAL;
run;
proc transpose data=_Q1 out=RES2(drop= _NAME_) delimiter=_;
var VAL;
id VNAME VISITN;
by ID;
run;
というわけ(IDの複数指定ができるようになったのは9.3から)。
1回途中で作ってる縦積み構造(_Q1)の中身をみてみると
となるわけです。
別にこっちの方法が正解だというわけではなく、状況に応じて考えましょうという話ですね。対象が文字列変数の場合、縦積み構造にするときに文字切れしないように最大lengthにしなければならないので注意が必要です。
SASの場合、BYやCLASSステートメントが強力なので、インプットやアウトプットの形にちょっと頭を使えば、同じ機能のステップを反復する必要がない状況が多いです。
まあ、言いたいことを一言で言うと、データステップも楽しい世界だよってことです。
縦積み作業もtransposeでやれば、初めての方は混乱するかも・・・
返信削除proc transpose data=Q1 out=_Q1(rename=Val1=Val) prefix=Val name=VName;
by Id VisitN;
var A B C;
run;
transposeを1回でなんとかならんかやってみたのですが無理でしたね。
out=の部分が間違っていました。
返信削除正しくは、out=_Q1(rename=(Val1=Val)) です。
有難うございます!2回transposeもありですね!
返信削除忘備録で「TRANSPOSEの2回実行テクニック」http://sas-boubi.blogspot.jp/2015/06/transpose2.htmlとして、既に紹介されてました。うっかりしてました。
気分を害されるかと思ったのですが、さすがに度量が広いですね!
返信削除2度漬けtransposeまで紹介していただけるとは感激です。
transposeだけで片付けると結びの「データステップも楽しい世界」が失効しますし、私のコメントこそ邪魔なのです。