Newsgroups: bit.listserv.sas-l
Date:         Thu, 20 Aug 1992 10:24:18 EDT
Reply-To:     Howard Schreier <HIS@NIHCU.BITNET>
From:         Howard Schreier <HIS@NIHCU.BITNET>
Subject: Re: ResetLagQueues function?

CONTENT:  Response/Comment
SUMMARY:  Can code a complex expression to behave as desired

> How can I reinitialize the LAG queue? On a BY variable change I want
> the queue to look like the beginning--filled with missing values.
>
> GROUP  X     Y=lag(X)    Desired Y
> 1      3       .            .
> 1      2       3            3
> 1      7       2            2
> 2      8       7            .
> 2      .       8            8
> 2      4       .            .

A very good question, I think.  I have  long  believed  that
SAS  should  have  a family of "LAGBY" functions which would
behave this way.

> The app this will sit in has a hundred BY variable changes, 100000
> observations, and multiple LAG queues, some of which go up to LAG20.
>
> I would prefer not to program my own LAG function with retains.
>
> I would prefer not to break up the original data set into a hundred
> small ones and use macro looping to process each separately and then
> recombine.
>
> Here is a sort of clumsy approach:
>
> data t;                  *sample data set generation;
>   do g=1 to 3;
>     do y=1 to 8;
>       output;
>     end;
>   end;

[code and results deleted]

> William Kahn
> W. L. Gore and Associates
> (410) 398-6400

The best I can do is another candidate for the kludge of the
year  award :-).  You could add a term to each LAG reference
which would contain parallel LAG references to each  of  the
BY  variables and would evaluate to zero if they all matched
and to missing otherwise.  For  your  test  case,  something
like this:

   data t;
     set t;
     by g;
     desiredy=lag6(y) + input(substr('.0',((lag6(g)=g)/*&...*/)+1,1),1.);
     *                       i      s     =                   =    s   i;

The comment line below the assignment statement just  labels
some  of  the  parentheses.   The third set from the outside
("=") surrounds the equality condition.  If there were  more
BY  variables,  each would have to be tested and the results
ANDed together.  Note:  this can give incorrect  results  if
there  are  multiple  BY  groups  with  the same BY variable
values (possible if NOTSORTED is coded).  The  SUBSTR  takes
the  result  and uses it to extract either the period or the
zero from the hard-coded string, and the INPUT  converts  it
to   numeric.    If  the  LAG  reference  crosses  BY  group
boundaries,  missing  value  propagation  causes  the  whole
expression to evaluate to missing, as desired.  The results:

   OBS    G    Y    DESIREDY

     1    1    1        .
     2    1    2        .
     3    1    3        .
     4    1    4        .
     5    1    5        .
     6    1    6        .
     7    1    7        1
     8    1    8        2
     9    2    1        .
    10    2    2        .
    11    2    3        .
    12    2    4        .
    13    2    5        .
    14    2    6        .
    15    2    7        1
    16    2    8        2
    17    3    1        .
    18    3    2        .
    19    3    3        .
    20    3    4        .
    21    3    5        .
    22    3    6        .
    23    3    7        1
    24    3    8        2

I really hope somebody else comes up with something  better.
This  solution  is  clean  in  that  it  doesn't  create any
additional variables, but it's still pretty ugly.

/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
\   Howard Schreier, U.S. Dept. of Commerce, Washington    /
/                     MVS 5.18 & 6.07                      \
\   Voice: (202) 377-4180        BITNET: HIS@NIHCU         /
/   Fax:   (202) 377-4614      INTERNET: HIS@CU.NIH.GOV    \
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
Comments: Gated by NETNEWS@AUVM.AMERICAN.EDU