Date: Fri, 15 Aug 2008 15:45:04 -0400
Reply-To: Nathaniel.Wooding@DOM.COM
Sender: "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From: Nat Wooding <Nathaniel.Wooding@DOM.COM>
Subject: Re: If else statement question
In-Reply-To: <081520081912.13997.48A5D5380000A8B4000036AD221357533305029A06CE9907@comcast.net>
Content-type: text/plain; charset=US-ASCII
Ian
As usual, this is a definite improvement on my code. As I expect you have
noted, I got hung up on trying to use a second set statement which is a
practice that I seldom need to use.
I wrote one end of my if statements using a < instead of an LE so I would
expect our results to vary slightly.
By the way, thinking of the If statements that check on the boundaries, it
occurs to me that one might cheat and write
limit = 2 + first.subject + last.subject;
Then one could write
if limit = 4 .... and get rid of the single cases
and at this point, we would know what the limits are and the second If
could be eliminated (Although it might have taken as long to create the
limit as it would to do the If.) Of course, we would still need the third
If.
Have a great weekend. Are they doing evening concerts at Longwood Gardens
this time of year?
Nat
Nat Wooding
Environmental Specialist III
Dominion, Environmental Biology
4111 Castlewood Rd
Richmond, VA 23234
Phone:804-271-5313, Fax: 804-271-2977
iw1junk@comcast.n
et
To
08/15/2008 03:12 "SAS(r) Discussion"
PM <SAS-L@LISTSERV.UGA.EDU>
cc
Nat Wooding
<Nathaniel.Wooding@DOM.COM>, sudip
chatterjee
<sudip.memphis@GMAIL.COM>
Subject
Re: If else statement question
Summary: Style
#iw-value=1
Nat,
The subject caught my eye, but I didn't answer at first because I
couldn't parse what was wanted. However, after seeing your code I
decided to show the following.
data q ;
merge sudip
sudip ( firstobs = 2 keep = rate rename = ( rate =
next_rate ) ) ;
/* one-to-one merge */
run ;
data q2 ;
set q ;
by subject ;
/* eliminate nonsense */
if first.subject and last.subject then
do ;
put "No comparison obs - deleting: " / _all_ ;
delete ;
end ;
/* set limit for comparison */
if first.subject or last.subject then limit = 3 ;
else limit = 2 ;
if first.subject then
comp_rate = next_rate ;
else
comp_rate = last_rate ;
ratio = rate / comp_rate ;
inv_ratio = 1 / ratio ;
test = ( 1/limit <= ratio <= limit ) ;
run ;
I find the preparatory step makes things clearer. There is also some
redundancy in testing for FIRST.SUBJECT and LAST.SUBJECT, but I think
this form much easier to modify, verify, and enforce uniformity. I
did not create the new rate variable although it is trivial to add
this.
I added the variable INV_RATIO to compare with your results. We
trivially differ when RATIO is exactly 2, and significantly differ on
the first observation of new subjects after the first.
Ian Whitlock
===============
Date: Fri, 15 Aug 2008 09:19:34 -0400
Reply-To: Nathaniel.Wooding@DOM.COM
Sender: "SAS(r) Discussion"
From: Nat Wooding <Nathaniel.Wooding@DOM.COM>
Subject: Re: If else statement question
Comments: To: sudip chatterjee <sudip.memphis@GMAIL.COM>
In-Reply-To:
<1ca751e30808141237w76e957eep70c8dfda1f22f205@mail.gmail.com>
Content-Type: text/plain; charset="US-ASCII"
Sudip
I took your "twice as" and it's counterparts to mean that any estimate
greater than twice its predecessor ( or less than half, etc) to mean
that
the rate was missing. Try the following code and see if it does what
you
need. Also, do you want to do a 1/3 or times 3 case for the last
instance
of a subject as well as for the very last obs.
The following code appears to be close to what you want but I have not
been
able to progromatically look ahead to the next obs for cases of the
first
instance of a subject other than the very first subject. Someone else
may
have some ideas on this.
Data Sudip;
input Subject time Rate ;
lastrate = lag(rate);
cards;
1 1950 11
1 1951 16
1 1952 25
1 1953 300
1 1954 200
1 1955 210
1 1956 1000
1 1957 2000
1 1958 1900
1 1959 1100
2 1950 1011
2 1951 1016
2 1952 1025
2 1953 1300
2 1954 1200
2 1955 1210
2 1956 1000
2 1957 2000
2 1958 1200
2 1959 1100
run;
Data Test;
set sudip ;
by Subject;
if _n_ = 1 then do;** first obs;
set sudip (firstobs=2 obs=2 keep = rate rename = (rate =
nextrate
));
ratio = nextrate/rate;
if .34 le ratio lt 3 then newrate = rate;
else newrate = .;
return;
end;
** the following loop is not working properly since I cannot think of
a way
to pass a live
** value to the firstobs and obs in a set statement like I used in the
last
loop.;
if first.subject then do;
Where = _n_ + 1 ;
set sudip ( keep = rate rename = (rate = nextrate ));
* set sudip ( where = ( count = nextobs) keep = rate rename = (rate =
nextrate ));
ratio = nextrate/rate;
if .34 le ratio lt 3 then newrate = rate;
else newrate = .;
return;
end;
ratio = rate / lastrate;
if last.subject then do;** last obs for a group ;
if .33 lt ratio lt 3 then newrate = rate;
else newrate = .;
return;
end;
if .50 lt ratio lt 2 then newrate = rate;
else newrate = .;
* drop nextrate;
run;
proc print;run;
Nat Wooding
Environmental Specialist III
Dominion, Environmental Biology
4111 Castlewood Rd
Richmond, VA 23234
Phone:804-271-5313, Fax: 804-271-2977
sudip chatterjee
<sudip.memphis@GM
AIL.COM>
To
Sent by: "SAS(r) SAS-L@LISTSERV.UGA.EDU
Discussion"
cc
<SAS-L@LISTSERV.U
GA.EDU>
Subject
If else statement question
08/14/2008 03:37
PM
Please respond to
sudip chatterjee
<sudip.memphis@GM
AIL.COM>
Dear User's
I have 100 subjects where rate of certain disease was estimated in 10
years time points
Say like this
Subject time Rate
1 1950 11
1 1951 16
1 1952 25
1 1953 300
1 1954 200
1 1955 210
1 1956 1000
1 1957 2000
1 1958 1900
1 1959 1100
2 1950 1011
2 1951 1016
2 1952 1025
2 1953 1300
2 1954 1200
2 1955 1210
2 1956 1000
2 1957 2000
2 1958 1200
2 1959 1100
Now what I want is to check every rate estimation each year and
if say an estimate is twice as big or small as previous year then I
put that as . Now for the first and last data I will check if that
rate is as 3 times high or smaller than its immediate neighbour if yes
I will put that as .
I need some idea to code this
Thanks
CONFIDENTIALITY NOTICE: This electronic message contains
information which may be legally confidential and/or privileged and
does not in any case represent a firm ENERGY COMMODITY bid or offer
relating thereto which binds the sender without an additional
express written confirmation to that effect. The information is
intended solely for the individual or entity named above and access
by anyone else is unauthorized. If you are not the intended
recipient, any disclosure, copying, distribution, or use of the
contents of this information is prohibited and may be unlawful. If
you have received this electronic transmission in error, please
reply immediately to the sender that you have received the message
in error, and delete it. Thank you.