/***************************************************************************************************************** SAS file name: Moving_Average.sas File location: _________________________________________________________________________________________________________________ Purpose: To present different ways of computing moving averages of time series in SAS Author: Peter Clemmensen Creation Date: 05/03/2017 This program supports the blog post "Moving Average ind SAS" on SASnrd.com *****************************************************************************************************************/ /* Example Data */ data testdata; input time value @@; datalines; 0 100 1 101 2 103 3 107 4 116 5 108 6 113 7 106 8 110 9 115 10 121 11 117 12 123 13 127 14 121 15 126 16 131 17 125 18 125 19 130 20 135 ; /* Data Step */ %let n=3; data DataStepMoveAv; retain s; set testdata; n=_n_; array count_{&n}; do i = &n to 2 by -1; count_[i]=count_[i-1]; end; count_[1]=value; if n < &n then MovAv = sum(of count_[*]) / n; else MovAv = sum(of count_[*]) / &n; retain count_:; drop i n; run; title "Backward Moving Average from Data Step"; proc sgplot data=DataStepMoveAv; series x=time y=MovAv / lineattrs=(color=red thickness=2) legendlabel="Moving Average";; scatter x=time y=value / markerattrs=(symbol=circlefilled color=black); keylegend / location=inside position=NW across=1 noborder; run; title; /* IML */ proc iml; use testdata; read all var _ALL_; close testdata; n=3; MovAv = j(nrow(value), 1, .); do i = 1 to nrow(value); idx = max(1,i-n+1):i; MovAv[i] = mean(value[idx]); end; title "Backward Moving Average from SAS/IML"; call series(time, MovAv); quit; /* Proc Expand */ proc expand data=testdata out=MoveAv method=none; id time; convert value = MovAv / transformout=(movave 3); convert value = WMovAv / transformout=(movave(1 2 3)); convert value = CMovAv / transformout=(cmovave 3); convert value = EWMovAv / transformout=(ewma .4); run; title "Moving Averages from PROC EXPAND"; proc sgplot data=MoveAv noautolegend; series x=time y=MovAv / lineattrs=(color=red thickness=2) legendlabel="Moving Average"; series x=time y=WMovAv / lineattrs=(color=blue thickness=2) legendlabel="Weighted Moving Average"; series x=time y=CMovAv / lineattrs=(color=green thickness=2) legendlabel="Centered. Moving Average"; series x=time y=EWMovAv / lineattrs=(color=gray thickness=2) legendlabel="Exp. Weighted Moving Average"; scatter x=time y=value / markerattrs=(symbol=circlefilled color=black); keylegend / location=inside position=NW across=1 noborder; run; title;