BookmarkSubscribeRSS Feed
Emjay
Obsidian | Level 7

Let's say I have the following:

 

data have;
input time count rate1 rate2 settings;
cards;
0.65 3 1.2 0.5 7
2.25 5 0.7 0.7 2
7 4 0.8 0.8 3
7 4 0.8 0.8 6
;
run;

Now I have the following rule for state '99':

 

data almost_want;
set have;
if 
(time<=1 and (
	(count>=1)
))
or
(1<time<=3 and (
	(count>=2 and rate1>0.55 and rate2>0.4)
))
or
(3<time and (
	(settings<=4 and count>=2 and rate1>0.55 and rate2>0.4)
	or
	(settings>=5 and count>=3 and rate1>0.55 and rate2>0.4)
))
then State=99;
run;

But what I actually want is this:

data want;
input time count rate1 rate2 settings State reason;
cards;
0.65 3 1.2 0.5 7 99 1
2.25 5 0.7 0.7 2 99 2
7 4 0.8 0.8 3 99 3
7 4 0.8 0.8 6 99 4
;
run;

 

So not only '99' but also because of which condition it is '99'.

 

In this example I have only one state cause it's enough to describe my problem but in the 'real' data it's five states with up to seven substatements per state.

 

Is there a way to find out which substatement of my if-condition was true?

 

So something like:

 

data almost_want;
set have;
if 
(time<=1 and (
	(count>=1)
	then reason=1
))
or
(1<time<=3 and (
	(count>=2 and rate1>0.55 and rate2>0.4)
	then reason=2
))
or
(3<time and (
	(settings<=4 and count>=2 and rate1>0.55 and rate2>0.4)
	then reason=3
	or
	(settings>=5 and count>=3 and rate1>0.55 and rate2>0.4)
	then reason=4
))
then State=99;
run;
4 REPLIES 4
Astounding
PROC Star

Don't try to do it all in one statement.  

 

if time <= 1 and count=1 then do;
   reason=1;
   state=99;
end;
else if (1 < time <= 3) and (count > 2 and rate1 > 0.55 and rate2 > 0.4) then do;
   reason=2;
   state=99;
end;
else .... similarly for other reasons

 

Using a few statements makes it easy.

Emjay
Obsidian | Level 7

Well, of course I could break it down in one if-statenment for every reason but I was hoping for an all-in-one-way...

ballardw
Super User

@Emjay wrote:

Well, of course I could break it down in one if-statenment for every reason but I was hoping for an all-in-one-way...


Since you couldn't provide a rule in a very concise manner in English that is often a clue that the code will not be brief either. Five variables, a different set for each time interval value, a mix of combinations of values I would find a very unlikely candidate for "all-in-one-way" code whatever that might be.

 

BTW, you want to be aware that < or <= (or LT and LE) conditions are true when a value is missing. If you do not want the evaluation

Emjay
Obsidian | Level 7

Yes, the conditions are a little nested, but that's unfortunately as it is.

 

With all-in-one I wasn't necessarily hoping for super short code, but maybe for a way to mark the true if-condition without writing a if-statement for every single one. I thought SAS maybe provides such a functionality...

 

But thanks for the hint with the < and missing values. Luckily I don't have those.

hackathon24-white-horiz.png

2025 SAS Hackathon: There is still time!

Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!

Register Now

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 4 replies
  • 1215 views
  • 2 likes
  • 3 in conversation