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.

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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
  • 890 views
  • 2 likes
  • 3 in conversation