Date: Sat, 6 May 2000 19:11:45 GMT
Reply-To: sashole@mediaone.net
Sender: "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From: Paul Dorfman <paul_dorfman@HOTMAIL.COM>
Subject: Re: computing difference between observations in a by group
Content-Type: text/plain; format=flowed
Paula,
OK, that makes it much more transparent. You have a file MOM like
ID V22
------
1 4
1 5
1 4
3 1
3 7
5 6
5 8
5 3
6 1
6 1
7 9
7 0
9 3
9 1
9 5
and want to create 3 files SAME, INCR, DECR depending on the relationship
between V22 in the first and last records in each ID group. Now, there are 2
possible variants: 1) you want the output files to contain the _entire_
qualifying groups, that is, you want them to look like
SAME INCR DECR
------ ------ ------
ID V22 ID V22 ID V22
------ ------ ------
1 4 3 1 5 6
1 5 3 7 5 8
1 4 9 3 5 3
6 1 9 1 7 9
6 1 9 5 7 0
2) you want only qualifying IDs:
SAME INCR DECR
---- ---- ----
ID ID ID
---- ---- ----
1 3 5
6 9 7
The task #2 is simple:
data same incr decr;
keep id;
set mom;
by id;
retain fv22;
if first.id then fv22 = v22;
if last.id then select;
when (v22 > fv22) output incr;
when (v22 < fv22) output decr;
otherwise output same;
end;
run;
The same can be accomplished shorter in 'retainless' form by enclosing each
by-group in an explicit loop:
data same incr decr;
do until (last.id);
set mom;
by id;
if first.id then fv22 = v22;
end;
if v22 > fv22 then output incr;
else if v22 < fv22 then output decr;
else output same;
keep id;
run;
Here RETAIN is unnecessary, because during the process of reading a
by-group, the bottom of the step is never reached, and therefore FV22
retains the same value for all iterations. When the group is done, the value
of V22 sitting in memory is the one from the bottom of the group and is
compared to FV22 acquired at the top. Only then FV22 is set to missing,
control is transferred to the top of the step, and processing of the next
group commences.
If you need the task #2 accomplished also, you now have everything you need:
data same incr decr;
merge mom(in=m) same(in=s) incr(in=i) decr(in=d);
by id;
if m;
if s then output same;
else if i then output incr;
else if d then output decr;
run;
Principally, #2 can be done in a single pass over MOM, but it requires some
look-ahead logic - you have to store a by-group somewhere before you know
that the last value in the group is. There is a variety of interesting ways
to do that, however, I am not sure it fits the thread.
Kind regards,
======================
Paul M. Dorfman
Jacksonville, FL
======================
>From: paula <icj808@USWEST.NET>
>Let me take Paul's advice and clarify what I want to accomplish here.
>
>I am trying to generate 4 baby sas data sets from a single mother data set,
>increase, decrease, nochange, and change. The criteron, as you may have
>known, is to see if the last value of V22 for a specific ID value is
>greater, less than, or equal to the first value of V22 for the same ID
>value. When this process is complete, the mother set remains intact.
>
>For example, for ID=1, since 35> 33, Id=1 belongs to Increase. For ID=2,
>since 30<39, it goes to Decrease, and so on.
________________________________________________________________________
Get Your Private, Free E-mail from MSN Hotmail at http://www.hotmail.com