SASの移動平均/STDEVの計算?
質問
ヘリーズ、
問題を明確にするのに役立つスクリーンショットを含めました。
http://i40.tinypic.com/mcrnmv.jpg.
何らかの移動平均と移動標準偏差を計算しようとしています。問題は、実際の値に対して変動係数(STDEV/AVG)を計算したいということです。通常、これは過去5年間STDEVとAVGを計算することによって行われます。ただし、私のデータベースには、過去5年間の情報がない(たぶん3、2など)観察がある場合があります。そのため、5年間の情報がない場合でも、AVGとSTDEVを計算するコードが必要です。
また、あなたが観察に見たように、5年以上にわたって情報がある場合があります。したがって、企業が7年間情報を持っている場合、AVGとSTDEVを計算するコードが必要です。たとえば、1997(1991-1996)、1998(1992-1997)および1999(1993-1998)などです。
私はSASコマンドにあまり精通していないので、それは次のように(非常に大まかに)見えるはずです
set var
if year = i then stdev=stdev(year(i-6) untill year(i-1)) and average = avg(year(i-6) untill year(i-1))
または、このようなもの、私は本当に手がかりがありません、私はそれを試してみようとしますが、自分でそれを見つけられないなら、それを投稿する価値があります。
ありがとう!
解決
私はここで読みやすくするためにここでProc SQLを提唱します。 Chang Chungのデータを例として使用すると、次のことを試すことができます。
/* test data */
data one;
input symbol $ value date :date9.;
format date date9.;
cards;
ABP1 -0.025 18feb1997
ABP1 0.05 25feb1998
ABP1 -0.025 05mar1999
ABP1 0.06 20mar2000
ABP1 0.25 05mar2001
ABP1 0.455 07mar2002
ABP1 0.73 25feb2003
ABP1 1.01 19feb2004
ABP1 1.25 16feb2005
ABP1 1.65 09feb2006
ABP1 1.87 08feb2007
ABT 0.555 14jan1991
ABT 0.6375 14jan1992
ABT 0.73 16jan1993
;
run;
proc sql;
create table two as
select distinct
a.symbol,
b.value,
year(a.date) as year,
b.date as date5
from
one a,
one b
where
a.symbol=b.symbol
and intck('year',b.date,a.date) between 1 and 5
order by
a.symbol,
year,
date5;
quit;
proc sql;
create table three as
select distinct
symbol,
year,
count(symbol) as n5,
avg(value) as avg5,
std(value) as std5
from
two
group by
symbol,
year;
quit;
他のヒント
それを行う正しい方法は、Proc拡張を使用することです。
あなたがそれで使用できる多くのオプションがありますが、あなたはやりたいかもしれません
PROC EXPAND DATA=TESTTEST OUT=MOVINGAVERAGE;
CONVERT VAL=AVG / TRANSFORMOUT=(MOVAVE 5);
RUN;
そして同様にMovstdのために。欠損値は自動的に無視しますが、その動作も調整できます
これが一つの方法です。お役に立てれば。
/* test data */
data one;
input symbol $ value date :date9.;
format date date9.;
cards;
ABP1 -0.025 18feb1997
ABP1 0.05 25feb1998
ABP1 -0.025 05mar1999
ABP1 0.06 20mar2000
ABP1 0.25 05mar2001
ABP1 0.455 07mar2002
ABP1 0.73 25feb2003
ABP1 1.01 19feb2004
ABP1 1.25 16feb2005
ABP1 1.65 09feb2006
ABP1 1.87 08feb2007
ABT 0.555 14jan1991
ABT 0.6375 14jan1992
ABT 0.73 16jan1993
;
run;
/* 5 year moving avg, stdev, cv assuming:
one obs per year from 1990 to 2010.
observations are already in the sorted order by symbol. */
%let START = 1990;
%let FINISH = 2010;
data two;
array val[%eval(&START-3):&FINISH] val1-val3 val&START-val&FINISH;
call missing(of val&START-val&FINISH);
do until (last.symbol);
set one;
by symbol;
year = year(date);
if &START<=year<=&FINISH then val[year] = value;
end;
do year = %eval(&START+2) to &FINISH;
avg5 = mean(val[year-5],val[year-4],val[year-3],val[year-2],val[year-1]);
std5 = std(val[year-5],val[year-4],val[year-3],val[year-2],val[year-1]);
cv5 = divide(std5,avg5);
if not missing(cv5) then output;
end;
keep symbol year avg5 std5 cv5;
run;
/* check */
proc print data=two;
run;
/* on lst
Obs symbol year avg5 std5 cv5
1 ABP1 1999 0.01250 0.05303 4.24264
2 ABP1 2001 0.01500 0.04637 3.09121
3 ABP1 2002 0.06200 0.11251 1.81461
4 ABP1 2003 0.15800 0.19457 1.23146
5 ABP1 2004 0.29400 0.30597 1.04071
6 ABP1 2005 0.50100 0.37786 0.75422
7 ABP1 2006 0.73900 0.40448 0.54734
8 ABP1 2007 1.01900 0.46185 0.45324
9 ABP1 2008 1.30200 0.46338 0.35590
10 ABP1 2009 1.44500 0.38726 0.26800
11 ABP1 2010 1.59000 0.31432 0.19769
12 ABT 1993 0.59625 0.05834 0.09784
13 ABT 1994 0.64083 0.08755 0.13662
14 ABT 1995 0.64083 0.08755 0.13662
15 ABT 1996 0.64083 0.08755 0.13662
16 ABT 1997 0.68375 0.06541 0.09566
*/