Search code examples
sasaveragestandardsdeviation

Calculating moving average/stdev in SAS?


Hye guys,

I included a screenshot to help clarify my problem:

http://i40.tinypic.com/mcrnmv.jpg.

I'm trying to calculate some kind of moving average and moving standard deviation. The thing is I want to calculate the coefficients of variation (stdev/avg) for the actual value. Normally this is done by calculating the stdev and avg for the past 5 years. However sometimes there will be observations in my database for which I do not have the information of the past 5 years (maybe only 3, 2 etc). That's why i want a code that will calculate the avg and stdev even if there is no information for the whole 5 years.

Also, as you see in the observations, sometimes I have information over more than 5 years, when this is the case I need some kind of moving average which allows me to calculate the avg and stdev for the past 5 year. So if a company has information for 7 years I need some kind of code that will calculate the avg and stdev for, lets say, 1997 (by 1991-1996), 1998 (by 1992-1997) and 1999 (1993-1998).

As i'm not very familiar with sas commands it should look (very very roughly) like:

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))

Or something like this, I really have no clue, I'm gonna try and figure it out but it's worth posting it if I won't find it myself.

Thanks!


Solution

  • I would advocate proc sql here for readability. Using Chang Chung's data as an example you could try the following:

    /* 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;