SQLソリューション:
data have;
input sub month y;
datalines;
1 1 1
1 2 2
1 3 3
1 5 5
;;;;
run;
proc sql;
create table want as
select H.sub,H.month, H.y, One.y as lag1, Two.y as lag2, Three.y as lag3
from have H
left join (select * from have) One on H.sub=One.sub and H.month=One.month+1
left join (select * from have) Two on H.sub=two.sub and H.month=Two.month+2
left join (select * from have) Three on H.sub=three.sub and H.month=Three.month+3
;
quit;
明らかに、36個必要な場合、これは少し長くなりますが、少なくともそれほど複雑ではありません。これを行うには、他にもさまざまな方法があります。LAGを使用しないでください。これは頭痛の種になり、とにかく適切ではありません。ハッシュの概念に精通している場合は、ハッシュテーブルの方が効率的で、コーディングも少なくて済みます。
ハッシュソリューション:
data want;
if _n_ = 1 then do;
declare hash h(dataset:'have(rename=y=ly)');
h.defineKey('sub','month');
h.defineData('ly');
h.defineDone();
call missing(sub,month,ly);
end;
set have;
array lags lag1-lag3;
do prevmonth = month-1 to month-3 by -1;
if prevmonth le 0 then leave;
rc=h.find(key:sub,key:prevmonth);
if rc=0 then lags[month-prevmonth] = ly;
call missing(ly);
end;
run;
これは、最大36 [または何でも]に拡張するのは非常に簡単です。配列の長さをに変更しarray lags lag1-lag36
、doステートメントdo prevmonth=month-1 to month-36 by -1;
を実行するだけです。必要な作業のほとんどは、月がここで機能するように配置することです。整数の月を作成するか、月/年などで機能するようにループ基準を変更します。あなたはあなたのデータがどのように指定されているかを示さないので、そこで助けることはできません。