BookmarkSubscribeRSS Feed
BogdanC
Fluorite | Level 6

I'd like to evaluate conditions that are stored in a character vector with an IF clause.

 

Ideally, the code below would print 2 and 3, but you'll noticed I used the vague denominator SomeFunction when evaluating the condition. My question is: Is there such a function, and if so, what's it named ?

 

proc iml;
	x = {1, 2 , 3, 4};
	cond = {"x[i] = 0", "x[i] > 0", "x[i] < 10", "x[i] = 10"};

	do i = 1 to 4;
		if SomeFunction(cond[i]) then do;
			print i;
		end;
	end;

quit;

 

 

If there is a 'cleaner' aproach to this, please let me know, I am not very familiar with IML so any advice is welcome.

 

7 REPLIES 7
Rick_SAS
SAS Super FREQ

Why do you want to evaluate character strings? Are these conditions not known until run time?

 

The usual approach is to use the SAS logical operators ('&', '|' and '^') to form logical expressions:

For example, if you want the AND logic, use

 

proc iml;
x = {1, 2 , 3, 4};
do i = 1 to 4;
	if x[i] >= 0 & x[i] <= 10 then do;
		print i;
	end;
end;

If you have very complicated logic and you want to isolate it in a function call, you can do the following, which returns 0 (FALSE) or 1 (TRUE) for various situations:

start EvalArg(a);
   if a = 0 | a = 10 then 
      return 0;
   else if a > 0 & a < 10 then 
      return 1;
   else 
      return 0;
finish;

do i = 1 to 4;
   if EvalArg( x[i] ) then do;
      print i;
   end;
end;
BogdanC
Fluorite | Level 6

Rick - thank you for the answer.
I think I didn't express myself clearly enough the first time: for each element in x there is a condition in cond. That condition can be different for each element, and I only need the elements in x for which the corresponding condition in cond evaluates to TRUE. 

 

I am NOT trying to concatenate all conditions into one and there is no connection bewtween the elements of cond.

 

Hopefully this makes more sense now.

Rick_SAS
SAS Super FREQ

You didn't answer my question: Why do you want to evaluate character strings? Are these conditions known at the time that you write the program?

BogdanC
Fluorite | Level 6

Some conditions are known, but some cannot be known beforehand (for instance, depending on the data, the variables that go into the condition are completely different).

The reason the 'fixed' conditions are in character strings is that they are read from an Excel file - the code has grown to a lot of line and it's easier to manage parameters and condition via Excel spraedsheets.

Rick_SAS
SAS Super FREQ

You say the conditions are data dependent, but how are they determined? SAS/IML can be programmed to incorporate data-dependent conditions such as

if x[i] < max(x) then ...

or 

if x[i] >= mean(x) + std(x) then ...

 

Instead of asking "how to evaluate a character expression in a spreadsheet," why not tell us what you are trying to accomplish. there might be an easier way to program the analysis.

Ksharp
Super User

Check CALL EXECUTEFILE()

 

another way is using data step to make a macro and execute it by %include  or CALL EXECUTE()

Rick_SAS
SAS Super FREQ

Yes. As KSharp says, it is clear HOW to do it. The questions is WHY would we do it this way if there are more efficient alternatives. And we won't know that unless we understand the process by which the conditions are generated.

 

proc iml;
start EvalStrCondition(x, s);
   cmd = "b = (" + s + ");";
   call execute(cmd);
   return b;
finish;

x = {1, 2 , 3, 4};
cond = {"x = 0", "x > 0", "x < 10", "x = 10"};

do i = 1 to 4;
   if EvalStrCondition(x[i], cond[i]) then do;
      print i;
   end;
end;

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!

Multiple Linear Regression in SAS

Learn how to run multiple linear regression models with and without interactions, presented by SAS user Alex Chaplin.

Find more tutorials on the SAS Users YouTube channel.

From The DO Loop
Want more? Visit our blog for more articles like these.
Discussion stats
  • 7 replies
  • 1728 views
  • 3 likes
  • 3 in conversation