BookmarkSubscribeRSS Feed
dera
Obsidian | Level 7

Hi,

 

Is there possible to do multiple "if then else" using do loops or array?

 

Here is what I want to do : I have a list of about 20,000 patients and I need to assign a code according to their diagnosis (these 350 codes are contained in macro variables and each of them run with a do-loop). Patients can have up to 10 codes assignment and instead of doing if-else-then 10 times, I would like to code something that is more efficient.

 

Here is what I have done :

FYI : "y" means that the patient has the corresponding diagnosis and "n" means that the patient does not have word such as "not, no sign of, etc.).

 

data want; set have;

if (y=1) and (n=0) and code1 = ' ' then do;
code = "&code";
flag_1 = 1;
end;

if (y=1) and (n=0) and code2 = ' ' then do;
code = "&code";
flag_2 = 1;
end;

if (y=1) and (n=0) and code3 = ' ' then do;
code = "&code";
flag_3 = 1;
end;

/* And so on until code10 */

My actual code verify if y=1, if n=0 and if the code1 variable is empty. If so, it assigns the corresponding code. If the code1 cariable is not empty, it goes to code2 variable and so on.

 

Can anyone help me making this code more efficient? I am looking for something that has a couple lines with a do-loop.

 

 

Thank you in advance.

 

6 REPLIES 6
novinosrin
Tourmaline | Level 20

You could

 

1. concatenate code1-code10

2. check if the concatentated value is missing 

3. if missing populate flag1-flag10 array as 1 and populate code1-code10 as &code

 

 

ballardw
Super User

@dera wrote:

Hi,

 

Is there possible to do multiple "if then else" using do loops or array?

 

Here is what I want to do : I have a list of about 20,000 patients and I need to assign a code according to their diagnosis (these 350 codes are contained in macro variables and each of them run with a do-loop). Patients can have up to 10 codes assignment and instead of doing if-else-then 10 times, I would like to code something that is more efficient.

 

Here is what I have done :

FYI : "y" means that the patient has the corresponding diagnosis and "n" means that the patient does not have word such as "not, no sign of, etc.).

 

data want; set have;

if (y=1) and (n=0) and code1 = ' ' then do;
code = "&code";
flag_1 = 1;
end;

if (y=1) and (n=0) and code2 = ' ' then do;
code = "&code";
flag_2 = 1;
end;

if (y=1) and (n=0) and code3 = ' ' then do;
code = "&code";
flag_3 = 1;
end;

/* And so on until code10 */

My actual code verify if y=1, if n=0 and if the code1 variable is empty. If so, it assigns the corresponding code. If the code1 cariable is not empty, it goes to code2 variable and so on.

 

Can anyone help me making this code more efficient? I am looking for something that has a couple lines with a do-loop.

 

 

Thank you in advance.

 


Your description might need some more details, such as possibly some actual values.

The code you show assigns the exact same of value of "&code" to the same variable multiple times.

Does this actually do what you want for code1? I see nothing that looks like a "corresponding code" assignment or detection.

This is somewhat more efficient code and at least more compact of the steps you demonstrate:

data want;
   set have;
   array c code1-code10; /*or however many code variables you have*/
   array flag_ {10}; /* number matches the number above*/
   if y=1 then do i= 1 to dim(c);
      if c[i]=' ' then do;
         code="&code.";
         flag_[i]=1;
      end;
   end;
run;
dera
Obsidian | Level 7
Hi ballardw,

Your code almost work! The only problem with it is that the assigned code is assign to code1, code2, until code10. Is there a way to tell SAS that when the code is assigned in the code1 variable, don't assign it again to the code2 variable?
novinosrin
Tourmaline | Level 20
data want;
set have;
array c(*) code:;
array flag {10};
if y=1 and n=0;
do until(k=0);
k=whichc(' ',of c(*));
if k=0 then leave;
c(k)="&code";
flag(k)=1;
end;
drop k; run;
ballardw
Super User

@dera wrote:
Hi ballardw,

Your code almost work! The only problem with it is that the assigned code is assign to code1, code2, until code10. Is there a way to tell SAS that when the code is assigned in the code1 variable, don't assign it again to the code2 variable?

Without input data, values such as the macro variable and what the result is supposed to actually look like it's pretty hard to tell what to suggest.

As I mentioned, it only shortens the code duplicating what you had. That is why I asked if what you wrote was actually doing what you intended.

 

Tom
Super User Tom
Super User

You should probably take a step back and explain more about the overall process.

Why not use the WHICHC() function to find out which is the first empty variable?

data have ;
 input id y n (code1-code3) ($);
cards;
1 1 0 . xxx yyy
2 1 0 aaa bbb .
3 1 0 ccc . .
4 1 0 a b c
5 0 1 d e .
6 1 1 f . .
7 0 0 g . .
;

%let code=NEW;

data want ;
  set have ;
  array code (3);
  array flag (3);
  loc = whichc(' ',of code(*));
  if y and ^n then do;
    if loc then do;
      code(loc)="&code";
      flag(loc)=1;
    end;
    else put "WARNING: No room to add '&code'." id= ;
  end;
  drop loc;
run;

 

image.png

But perhaps you just want one "flag" variable? In which case why not have it store which position was used to add the new code?

data want ;
  set have ;
  array code (3);
  loc = whichc(' ',of code(*));
  if y and ^n then do;
    if loc then code(loc)="&code";
  end;
  else loc=-1;
run;

image.png

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 6 replies
  • 1292 views
  • 0 likes
  • 4 in conversation