DATA Step, Macro, Functions and more

Do Loop with IF in Macro

Accepted Solution Solved
Reply
New Contributor
Posts: 4
Accepted Solution

Do Loop with IF in Macro

Hi,

I've been struggling with a do loop in SAS and would be grateful for any assistance. This is the data I have:

data have;

input Parameter $ COL1 $ COL2 $;

  cards;

Intercept AGE DRINKPATTERN

DRINKPATTERN AGE DRINKPATTERN

DRINKPATTERN AGE DRINKPATTERN

DRINKPATTERN AGE DRINKPATTERN

DRINKPATTERN AGE DRINKPATTERN

FISHLASTWEEK AGE DRINKPATTERN

AGE AGE DRINKPATTERN AGE DRINKPATTERN

AGE AGE DRINKPATTERN AGE DRINKPATTERN

AGE AGE DRINKPATTERN AGE DRINKPATTERN

FISHLASTWEEK*AGE AGE DRINKPATTERN

FISHLASTWEEK*AGE AGE DRINKPATTERN

FISHLASTWEEK*AGE AGE DRINKPATTERN

;

run;

I want to assess whether the string values contained in the variables COL1 or COL2 are evident in the field Parameter and if so assign a value of 2 to the variable TYPE.

The macro I created is below. The problem I am having is that the if statement does not seem to generate and the mprint option highlights this. Any assistance

is greatly appreaciated,

thanks,

%macro ClassIdentifier(value);

data want;

set have;

TYPE = 1;

   %do i=1 %to &Value;

   %let Varname = COL&i;

      %if %index(Parameter, &Varname ) NE 0 %then TYPE = 2;

      run;

   %end;

%mend;

options mprint;

%ClassIdentifier(2)


Accepted Solutions
Solution
‎12-16-2014 11:34 AM
Super Contributor
Posts: 340

Re: Do Loop with IF in Macro

An alternative;

%macro ClassIdentifier(value);
data want (Drop=i);
set have;
Type=1;
Array C{*} $30. COL:;
Do i=1 To Dim(C);
  If Index(Parameter,C{i}) Then Type=2;
  Else Type=Min(Type,2);
End;
Run;
%mend;
%ClassIdentifier(value=2)

View solution in original post


All Replies
Super User
Super User
Posts: 7,970

Re: Do Loop with IF in Macro

Why do you need a macro?  You could just create a flag in you read:

data have;

input Parameter $ COL1 $ COL2 $;

flag1=index(parameter,col1);  /* Flag for first one */

flag2=index(parameter,col2);   /* Flag for second */

  cards;

Intercept AGE DRINKPATTERN

DRINKPATTERN AGE DRINKPATTERN

DRINKPATTERN AGE DRINKPATTERN

DRINKPATTERN AGE DRINKPATTERN

DRINKPATTERN AGE DRINKPATTERN

FISHLASTWEEK AGE DRINKPATTERN

AGE AGE DRINKPATTERN AGE DRINKPATTERN

AGE AGE DRINKPATTERN AGE DRINKPATTERN

AGE AGE DRINKPATTERN AGE DRINKPATTERN

FISHLASTWEEK*AGE AGE DRINKPATTERN

FISHLASTWEEK*AGE AGE DRINKPATTERN

FISHLASTWEEK*AGE AGE DRINKPATTERN

;

run;

New Contributor
Posts: 4

Re: Do Loop with IF in Macro

Hi, thanks for the responses. I need a loop, (maybe not a macro) as there will be multiple fields all with COL at the beginning.

data have;

input Parameter $ COL1 $ COL2 $;

  cards;

Intercept AGE DRINKPATTERN

DRINKPATTERN AGE DRINKPATTERN

DRINKPATTERN AGE DRINKPATTERN

DRINKPATTERN AGE DRINKPATTERN

DRINKPATTERN AGE DRINKPATTERN

FISHLASTWEEK AGE DRINKPATTERN

AGE AGE DRINKPATTERN

AGE AGE DRINKPATTERN

AGE AGE DRINKPATTERN

FISHLASTWEEK*AGE AGE DRINKPATTERN

FISHLASTWEEK*AGE AGE DRINKPATTERN

FISHLASTWEEK*AGE AGE DRINKPATTERN

;

run;

Using the data above, I can create  a new field using a data step with the following:

data want;

set have;

Type = 1;

if index(Parameter, col1 ) NE 0 then Type = 2;

run;

I would like this to run in a loop and replace the col1 with col2 etc

the output should have an additional field TYPE that has a value of 2 if the strings in col1 or col2 are found in the field parameter:

Parameter                    Col1     Col2                    Type

Intercept                   AGE      DRINKPATTERN     1

DRINKPATTERN     AGE      DRINKPATTERN     2

DRINKPATTERN     AGE      DRINKPATTERN     2

DRINKPATTERN     AGE      DRINKPATTERN     2

DRINKPATTERN     AGE      DRINKPATTERN     2

FISHLASTWEEK      AGE      DRINKPATTERN     1

AGE                         AGE      DRINKPATTERN     2

apologies for omissions previously, I will try the macro with the array, thank you

New Contributor
Posts: 4

Re: Do Loop with IF in Macro

Hi,

thanks for the responses. I used the array and it works great, thank you. I'm still a bit miffed about the IF statement not functioning in the loop however ... maybe for another day!

Regards,

Michael

Occasional Contributor pwe
Occasional Contributor
Posts: 11

Re: Do Loop with IF in Macro

" I'm still a bit miffed about the IF statement not functioning in the loop however "

are you referring to the line:   

     %if %index(Parameter, &Varname ) NE 0 %then TYPE = 2;

or the line:

     If   index(Parameter, col1 ) NE 0 then Type = 2;

New Contributor
Posts: 4

Re: Do Loop with IF in Macro

Hi, the line:

%if %index(Parameter, &Varname ) NE 0 %then TYPE = 2;

I managed to get a little help with this and found it was an easy fix, just remove the % symbols as:

if index(Parameter, &Varname ) NE 0 then TYPE = 2;

Works great now. I also implemented the array version as an alternative.

thanks for the response

Occasional Contributor pwe
Occasional Contributor
Posts: 11

Re: Do Loop with IF in Macro

Yes, the line 

%if %index(Parameter, &Varname ) NE 0 %then TYPE = 2;

was working correctly, your expectations were wrong Smiley Happy

You were using macro statements where you should have used data step statements. A common problem when trying to learn and apply macro.

Super User
Posts: 11,343

Re: Do Loop with IF in Macro

It will help if you provide an example of what you expect for output.

Did you create a basic data step that provided the desired output before attempting the macro approach? If so, please post that.

If you want to see if the variable Parameter in have contains the text COL1 you want:

  if   index(Parameter,"COL&I") , no need to create the additional macro variable. You are getting false for the result as the string

Parameter does not contain COL1 or COL2. The macro processor not the data step evaluates the %index function and %if / %then.

Also, the index function is case sensitive so you may want index (upcase(Parameter),"COL&I").

%do I=1 to &value;

      if   index(Parameter,"COL&I")  ne 0 then type=2;

%end;

run;

The if loop should then generate:

if index(Parameter,"COL1") ne 0 then type=2;

if index(Parameter,"COL2") ne 0 then type=2;

Also having the %do %end enclose the Run statement you could be generating at least one Run without a data step associated.

Solution
‎12-16-2014 11:34 AM
Super Contributor
Posts: 340

Re: Do Loop with IF in Macro

An alternative;

%macro ClassIdentifier(value);
data want (Drop=i);
set have;
Type=1;
Array C{*} $30. COL:;
Do i=1 To Dim(C);
  If Index(Parameter,C{i}) Then Type=2;
  Else Type=Min(Type,2);
End;
Run;
%mend;
%ClassIdentifier(value=2)

🔒 This topic is solved and locked.

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

Discussion stats
  • 8 replies
  • 599 views
  • 3 likes
  • 5 in conversation