JasonR
JasonR

Reputation: 409

SAS - Writing an if Statement with a Do Loop inside

I am trying to help a colleague with a SAS Script she is working with . I am a programmer so I understand the logic, however I don't now the syntax in SAS. Basically this is what she is trying to do.

We have:

Array of Procedure Dates (proc_date[i]) 
Array of Procedures (proc[i]).

Each record in our data can have up to 20 Procedures and 20 dates.

i=20

Each procedure has an associated code, lets just say there are 100 different codes where codes 1 to 10 is ProcedureA, 11 to 20 is ProcedureB etc etc.

We need to loop through each Procedure and assign it the correct ProcedureCategory if it falls into 1 of the 100 codes (ie: it enters one of the If Statements). When this is true we then need to loop through each other corresponding Procedure Date in that row, if they are different dates when we add the 'Weighted Values' together, else we would just take the greater of the 2 values.

I hope that helps and I hope this makes sense. I could write this in another language (ie: C/C++/C#/VB) however I'm at a loss with SAS as I'm just not that familiar with the syntax and the logic doesn't seem to be that other OO languages.

Thanks in advance for any assistance. Kind Regards.

Upvotes: 0

Views: 682

Answers (2)

Ron Fehd
Ron Fehd

Reputation: 11

Here are some statements mentioned.

*codes 1 to 10 is ProcedureA, 11 to 20 is ProcedureB ;

proc format;
value codes 1-10 = 'A'
           11-20 = 'B';

Procedure(i) = put(code,codes.);

another way to recode ranges is with the between syntax

if 1 <= value <= 10 then variable = <new-value>;

hth

Upvotes: 1

Joe
Joe

Reputation: 63424

You don't want to do 100 if statements, one way or the other.

The answer to the core of your question is that you need the do loop outside of the if statement.

data want;
  set have;
  array proc[20];
  array proc_date[20];
  do _i = 1 to dim(proc); *this would be 20;
    if proc[_i] = 53 then ... ;
    else if proc[_i] = 54 then ...;
  end;
run;

Now, what you're trying to do with the proc_date sounds like you need to do something with proc_date[i] in that same loop. The loop is just an iterator - the only thing changing is _i which is used as an array index. It's welcome to be the array index for either array (or to do any other thing). This is where this differs from common OOP practice, since this isn't an array class; you're not using the individual object to iterate it. This is a functional language style (c would do it the same way, even).

However, the if/else bits there would be unwieldy and long. In SAS you have a lot of ways of dealing with that. You might have another array of 100 values proc can take, and then inside that do loop have another do loop iterating over that array (do _j = 1 to 100;) - or the other way around (iterate through the 100, inside that iterate through the 20) if that makes more sense (if you want to at one time have all of the values).

data want;
  set have;
  array proc[20];
  array proc_date[20];
  array proc_val[100];  *needs to be populated in the `have` dataset, or in another;
  do _i = 1 to dim(proc_val);
    do _i = 1 to dim(proc);
      if proc[_j] = proc_val[_i] then ...;  *this statement executes 100*20 times;
    end;
  end;
run;

You also could have a user-defined format, which is really just a one-to-one mapping of values (start value -> label value). Map your 100 values to the 10 procedures they correspond to, or whatever. Then all 100 if statements become

proc_value[_i] = put(proc[_i],PROCFMT.);

and then proc_value[_i] stores the procedure (or whatever) which you then can evaluate more simply hopefully.

You also may want to look into hash tables; both for a similar concept as the format above, but also for doing the storage. Hash tables are a common idea in programming that perhaps you've already come across, and the way SAS implements them is actually OOP-like. If you're trying to do some sort of summarization based on the procedure values, you could easily do that in a hash table and probably much more efficiently than you could in IF statements.

Upvotes: 1

Related Questions