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 prevmonth=month-1 to month-36 by -1;
最多的工作,你可能需要做是安排的東西,所以月份在這裏工作 - 無論是通過創建一個整數月份,或更改循環標準與月/年或什麼不工作。你不顯示你的數據是如何指定的,所以不能幫助你。
來源
2013-02-08 22:11:10
Joe
「滯後取決於時間」是什麼意思?我沒有看到名爲「time」的變量。另外,給定原始數據集,第二個數據塊是否正是您想要的結果? – BellevueBob 2013-02-08 21:43:09
@BobDuell我很抱歉混淆。我只是將變量'time'改爲'month',以使我的問題更清晰。是的,第二個是我想要的。 – liuminzhao 2013-02-08 21:44:36
我很抱歉,但我不明白你想要做什麼。對於第四個obs,「lag2」等於「3」以什麼方式?是否因爲月份存在差距(就好像有一行「月份= 4」)? – BellevueBob 2013-02-08 22:11:33