これにより、希望する答えにできるだけ近づけることができます。おそらく必要とされるよりもはるかに複雑ですが、lob_id が prec1-3 にとどまることを保証します。複数の変数に同じ変数名を付けることはできませんが、同じラベルを付けることができるので、_1 _2 _3 などを追加しながらラベルを同じにします。
出力ウィンドウにこれが必要な場合は、データセットを PROC PRINT することができます (ラベルが表示され、出力に目的の繰り返し変数名が表示されます)。
data have;
input pr_id lob_id $ prec1 prec2 prec3;
datalines;
112 1a 3478 56 77
112 1b 3466 65 43
112 1c 5677 57 68
112 1d 5634 49 52
215 2a 1234 43 45
215 2b 9787 32 43
215 2c 4566 39 90
388 3a 8797 88 99
388 3b 6579 58 72
388 3c 9087 76 67
;;;;
run;
data have_pret;
set have;
by pr_id;
array precs prec:;
if first.pr_id then counter=0;
counter+1;
varnamecounter+1;
valuet=lob_id;
idname=cats("lob_id",'_',counter);
idlabel="lob_id";
output;
call missing(valuet);
do __t = 1 to dim(precs);
varnamecounter+1;
valuen=precs[__t];
idname=cats('prec',__t,'_',counter);
idlabel=vlabel(precs[__t]);
output;
end;
call missing(valuen);
keep pr_id valuet valuen idname idlabel varnamecounter;
run;
proc sort data=have_pret out=varcounter(keep=idname varnamecounter);
by idname varnamecounter;
run;
data varcounter_fin;
set varcounter;
by idname varnamecounter;
if first.idname;
run;
proc sql;
select idname into :varlist separated by ' '
from varcounter_fin order by varnamecounter;
quit;
proc transpose data=have_pret(where=(not missing(valuen))) out=want_n;
by pr_id;
var valuen;
id idname;
idlabel idlabel;
run;
proc transpose data=have_pret(where=(missing(valuen))) out=want_t;
by pr_id;
var valuet;
id idname;
idlabel idlabel;
run;
data want;
retain pr_id &varlist.;
merge want_n want_t;
by pr_id;
drop _name_;
run;
これを SQL で行うのは面倒です。SAS は、すべてをハードコーディングせずに適切に転置できる高度な SQL テーブル関数をサポートしていません。それは次のようなものになります
proc sql;
select pr_id,
max(lob_id1) as lob_id1, max(prec1_1) as prec1_1, max(prec2_1) as prec2_1, max(prec3_1) as prec3_1,
max(lob_id2) as lob_id2, max(prec1_2) as prec1_2, max(prec2_2) as prec2_2, max(prec3_2) as prec3_2 from (
select pr_id,
case when substr(lob_id,2,1)='a' then lob_id else ' ' end as lob_id1,
case when substr(lob_id,2,1)='a' then prec1 else . end as prec1_1,
case when substr(lob_id,2,1)='a' then prec2 else . end as prec2_1,
case when substr(lob_id,2,1)='a' then prec3 else . end as prec3_1,
case when substr(lob_id,2,1)='b' then lob_id else ' ' end as lob_id2,
case when substr(lob_id,2,1)='b' then prec1 else . end as prec1_2,
case when substr(lob_id,2,1)='b' then prec2 else . end as prec2_2,
case when substr(lob_id,2,1)='b' then prec3 else . end as prec3_2
from have )
group by pr_id;
quit;
しかし、3 と 4 を含めるように拡張しました。SQL でこれを行うのがばかげている理由がわかると思います :) SAS コードはおそらく実際には短く、これを簡単に拡張できるようにするためにはるかに多くの作業を行っています。たとえば、ステートメントを保持することをハードコードしただけです。