Date: Tue, 14 Nov 2006 22:26:27 -0500
Reply-To: "Richard A. DeVenezia" <rdevenezia@WILDBLUE.NET>
Sender: "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From: "Richard A. DeVenezia" <rdevenezia@WILDBLUE.NET>
Subject: Re: Moving maximum
Haigang Zhou wrote:
> I realized that I can do it by the following code using the LAG
> function:
>
> data aaa;
> input x;
> cards;
> 2
> 1
> 5
> 7
> 4
> 3
> 2
> 5
> 5
> 3
> 8;
> run;
>
> data aaa; set aaa;
> max = max(x, lag(x), lag2(x), lag3(x), lag4(x));
> run;
>
> However, if I want to find the 50-day moving average, using the above
> code will be tedious. Is there an easier way?
A ring array is one way to manually perform rolling computations.
In the following, a little smarts prevents the need to perform 1e6 MAX
calls.
--------------------------------------------
data foo;
top = 1e6;
do x = 1 to top;
y = x * sin(x/top*50);
output;
end;
drop top;
run;
/** /
symbol1 v=point i=join;
proc gplot data=foo;
plot y*x;
run;
/**/
data foomax500;
set foo end=end;
array actives[500];
retain actives1-actives500;
drop actives1-actives500;
retain i 0 lastmax .;
i + 1;
if i > dim(actives) then i = 1;
actives[i] = y;
if y > lastmax then do;
max500 = y;
unis + 1;
end;
else do;
max500 = max (of actives[*]);
maxis + 1;
end;
lastmax = max500;
drop i lastmax unis maxis;
if end then put unis= maxis=;
run;
--------------------------------------------
Here is a link to another sample using ring arrays
http://www.devenezia.com/downloads/sas/samples/rolling-back-sums.sas
--
Richard A. DeVenezia