BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
twenty7
Obsidian | Level 7

Hi,

 

I'm trying do have a do loop within a macro but can't seem to get it to work

 

the data I have...

data have;
input id $ severity_1 $ severity_2 $ severity_3 $;
datalines;
001 WARNING N/A N/A 
002 N/A N/A N/A 
003 N/A WARNING N/A
run;

what I want to do...

data want;
set have;
if severity_1 = "WARNING" or severity_2 = "WARNING" or severity_3 = "WARNING" then data_invalid = "Y"; else data_invalid = "N";
run;

the reason I want a do loop is because there will be 100 severity columns

 

what I have so far (that does not seem to work)...

 

%macro data_invalid();
data want2;
set have;
%let i=1;
%do %while (i < 3);
%if severity_&i = "WARNING" %then data_invalid = "Y" %else data_invalid = "N"
%end;
run;
%mend;
%data_invalid();

proc freq data = want2;
table data_invalid /missing;
run;

the error  I get is "variable data_invalid not found"

 

Help?

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

This is NOT a macro problem. Just use an ARRAY in the data step.

data want;
   set have;
   array sev severity_1 - severity_3 ;
   data_invalid = "N";
   do index=1 to dim(sev) while ( data_invalid = "N");
     if sev[index] = "WARNING" then data_invalid = "Y"; 
   end;
   drop index;
run;

View solution in original post

7 REPLIES 7
Shmuel
Garnet | Level 18

You don't need a macro but use a whichc() function  on an array:

data invalid;
 set have;
      array sx {} $ severity_: ;   /* or severity_1 - severity_3 */
     if whichc(sx(*)) = "WARNING" then data_invalid = "y"; else data_invalid = "N";
run;

 

Tom
Super User Tom
Super User

@Shmuel wrote:

You don't need a macro but use a whichc() function  on an array:

data invalid;
 set have;
      array sx {} severiity_: ;   /* or severity_1 - severity_3 */
     if whichc(sx(*)) = "WARNING" then data_invalid = "y"; else data_invalid = "N";
run;

 


Correction on syntax of the WHICHC() function.  Also another advantage of using WHICHC() for this is you don't need to define the array.  Just use the variable list in the function call.

data invalid;
  set have;
  if whichc("WARNING", of severity_:) then data_invalid = "Y";
  else data_invalid = "N";
run;
Shmuel
Garnet | Level 18

Thank you @Tom 

Tom
Super User Tom
Super User

This is NOT a macro problem. Just use an ARRAY in the data step.

data want;
   set have;
   array sev severity_1 - severity_3 ;
   data_invalid = "N";
   do index=1 to dim(sev) while ( data_invalid = "N");
     if sev[index] = "WARNING" then data_invalid = "Y"; 
   end;
   drop index;
run;
twenty7
Obsidian | Level 7

thanks once again @Tom 

gamotte
Rhodochrosite | Level 12

@Shmuel 's answer.

 

Given that macro are not needed, there are several reasons your macro doesn't work :

 

- You use macro %if...%then...%else but should use regular if...then...else as the macro versions

only make text comparisons. So the condition severity_&i = "WARNING"  will compare two strings

(for &i.=2, for instance),  severity_2 (wo quotes) and "WARNING" (with quotes) and will never be true

 

- You repeat the test for each value of &i. so that only the last test will influence the final value of invalid_data.

You should generate a series of tests separated by "or".

 

- You forgot a semi-colon after %then data_invalid = "Y" 

 

Also, you can use a simple %do loop :

%do i=1 %to 3;

...

%end;

FreelanceReinh
Jade | Level 19

Hi @twenty7,

 

Alternatively you can use the IN operator with an array:

data want;
set have;
array s[*] sev:;
data_invalid='WARNING' in s;
run;

Note that this creates a numeric, 0-1 coded variable data_invalid, which is more convenient than a character variable in most applications. Apply a format if you need to see "N" and "Y" in your output.

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
  • 7 replies
  • 743 views
  • 1 like
  • 5 in conversation