Coding efficiency SAS program

Accepted Solution Solved
Reply
Contributor
Posts: 59
Accepted Solution

Coding efficiency SAS program

Dear SAS support communities:

I have sas code and it works, but the code is not efficiency at all.

How can I rewrite the code more efficient with same output ?

Data  <output>;

  set <input> ;

  code = 'unmatch';  /* new var */

  if code='unmatch' and if <condition 1 satisfied> then code = '111';

  if code='unmatch' and if <condition 2 satisfied> then code = '222';

  if code='unmatch' and if <condition 3 satisfied> then code = '333';

  ...............................................................

  if code='unmatch' and if <condition 9 satisfied> then code = '999';

  run;

if a value is assigned to code then sas enter the next round of input,

otherwise; the code is still unmatch after condition 9.

  Thanks for sharing your knowledge.

  William


Accepted Solutions
Solution
‎07-10-2015 10:17 AM
Super User
Super User
Posts: 7,977

Re: Coding efficiency SAS program

Posted in reply to wtien196838

Ah, I think I see.  Your not talking about whether the program runs quickly or uses less resources.  What you are talking about is maintaining that large amount of if statements.  You could consider putting the conditions in a separate table, maybe something like:

VAR          TEST          VAL          RESPONSE

A                =                  1               111

B                <                   10            222

...

Then you can use that to generate your code out as:

data _null_;

     set tests end=last;

     if _n_=1 then call execute('data want; set have; if code='unmatch' then do; ')

     call execute(cats(' if ',var,test,val,' then code="',response,'"');     

     if last then call execute('run;');

run;


Then its just a matter of fiddling with the tests dataset rather than the code.  Note, you may have to change it slightly, I assumed all numeric test, if some are text, some numeric then you need to code round it.

View solution in original post


All Replies
Super User
Posts: 19,833

Re: Coding efficiency SAS program

Posted in reply to wtien196838

Add condition

if code=unmatch to the top rather than check at each line, but since you set it at the beginning I'm not sure why it's necessary at all.

Why not if/else if rather than several ifs?

What are the other conditions?

if code='unmatch' then do;

if <condition1> then code='111'

else if <condition2> then code='222'

...

else if <condition9> then code='999';

end;

Super User
Posts: 5,513

Re: Coding efficiency SAS program

Posted in reply to wtien196838

As Reeza pointed out, there are some savings possible by altering the IF/THEN statements and adding ELSE.  Another possibility (assuming that ELSE makes sense logically):

data want;

set have;

length code $ 7;

if (condition 1) then code='111';

else if (condition 2) then code='222';

...

else if (condition 9) then code='999';

else code='unmatch';

run;

Also note, you don't have to go in order if your conditions are mutually exclusive.  For example, you could code "999" first, if that is the most prevalent value.  However ...

These savings will be relatively small.  The most important thing you can do in this program is inspect which variables are needed and which are not.  Add KEEP= or DROP= on the SET statement to limit reading in variables to only those that are needed:

data want;

set have (keep=var1-var20);

......

run;

The expense of reading in data far outweighs the expense of calculations.

Good luck.

Super User
Posts: 11,343

Re: Coding efficiency SAS program

Posted in reply to wtien196838

Also look at the SELECT structure

if code = 'unmatch' then do;

     select;

          when (<condition 1>) code='111';

          when (<condition 2>) code='222';

          /* repeat as needed*/

          when (<condition 9>) code='999';

          otherwise ; /* something to do when none of the conditions is met*/

     end;

end;

NOTE: you can do multiple things for a condition by using Do; <statement1>;<statement2>; end;

With your example I would not bother with the assigning unmatch and checking but use the following:

     length code $ 7; /* large enough to hold the longest code */

     select;

          when (<condition 1>) code='111';

          when (<condition 2>) code='222';

          /* repeat as needed*/

          when (<condition 9>) code='999';

          otherwise code='unmatch' ;

     end;

PROC Star
Posts: 1,167

Re: Coding efficiency SAS program

Posted in reply to wtien196838

In addition to Reeza's comments, when you have two comparisons use syntax

if code='unmatch' and <condition 1> then code = '111';

instead of

if code='unmatch' and if <condition 1 satisfied> then code = '111';

(you have an extra `if` statement which will cause problems).

Tom

Contributor
Posts: 59

Re: Coding efficiency SAS program

Posted in reply to wtien196838

Thanks for all suggestions. The reason that I raise this question is that each condition is a full page (when print out hard copy) of hard coding IF/ELSE or other statements for verification before I assigned the value to code. The SELECT statement can not apply here. IF/ELSE statement works as I am coding now. I need to find a coding method that boost up the program efficiency.

Super User
Posts: 5,432

Re: Coding efficiency SAS program

Posted in reply to wtien196838

Usually, coding doesn't effect execution time that much - it's still a straight pass through data. Cab´n tou share some CPU statistics?

I'm more interested in the vast amount of hard coded logic, not very maintenance friendly. Can you give an example of your <condition n>? It would be wise to find a data driven way to handle the logic.

Data never sleeps
Super User
Posts: 19,833

Re: Coding efficiency SAS program

Posted in reply to wtien196838

Without knowing what the conditions are we can't really comment beyond that. Have you optimized those conditions?

Super User
Posts: 11,343

Re: Coding efficiency SAS program

Posted in reply to wtien196838

I would be interested in see what you have that SELECT won't work for. There are two forms:

Select (expression); that evaluates a single expression and executes the appropriate WHEN block.

The other Select; allows different expressions for each when block.

I really  hate the idea of nesting that many If then else and keeping things straight.

Solution
‎07-10-2015 10:17 AM
Super User
Super User
Posts: 7,977

Re: Coding efficiency SAS program

Posted in reply to wtien196838

Ah, I think I see.  Your not talking about whether the program runs quickly or uses less resources.  What you are talking about is maintaining that large amount of if statements.  You could consider putting the conditions in a separate table, maybe something like:

VAR          TEST          VAL          RESPONSE

A                =                  1               111

B                <                   10            222

...

Then you can use that to generate your code out as:

data _null_;

     set tests end=last;

     if _n_=1 then call execute('data want; set have; if code='unmatch' then do; ')

     call execute(cats(' if ',var,test,val,' then code="',response,'"');     

     if last then call execute('run;');

run;


Then its just a matter of fiddling with the tests dataset rather than the code.  Note, you may have to change it slightly, I assumed all numeric test, if some are text, some numeric then you need to code round it.

Contributor
Posts: 34

Re: Coding efficiency SAS program

Posted in reply to wtien196838

It seems that you are asking how to write code that is parsimonious as opposed to writing a program that will run quickly. You can use a macro loop to achieve your goal. Something like this:

%macro Compare;

data output;

set input;

code='unmatch';

%let counter=1;

%do %while &counter <= 9;

  if code='unmatch' then do;

       if <condition &counter. satisfied> then code=put(111*&counter.,3.);

  end;

  %let counter=%eval(&counter.+1);

end;

run;

%mend;

%Compare;

🔒 This topic is solved and locked.

Need further help from the community? Please ask a new question.

Discussion stats
  • 10 replies
  • 318 views
  • 6 likes
  • 8 in conversation