DATA Step, Macro, Functions and more

If then Scan Macro

Reply
Super Contributor
Posts: 704

If then Scan Macro

TIn the below macro, I expect to see the variable X to be "Finance Data" if the dname takes dataset.tsv as parameter and 

X will be "Scores,Income" when dname takes dataset_scores.tsv or dataset_income.tsv.

But I see only "Finance Data" as the value.

 

%macro xyz(dname=);
data t;
Length X $15;
%if (%scan(&dname.,-1,'_') ne 'scores.tsv' or %scan(&dname.,-1,'_') ne 'income.tsv') %then %do;
x='Finance Data';
%end;
%else %do;
X='Scores,Income';
%end;
run;
%mend xyz;
%xyz(dname=dataset_scores.tsv);
%xyz(dname=dataset_income.tsv);
%xyz(dname=dataset.tsv);

PROC Star
Posts: 1,605

Re: If then Scan Macro

Try removing quotes like -

 

%macro xyz(dname=);
data t;
Length X $15;
%if (%scan(&dname.,-1,'_') ne scores.tsv or %scan(&dname.,-1,'_') ne income.tsv) %then %do;
x='Finance Data';
%end;
%else %do;
X='Scores,Income';
%end;
run;
%mend xyz;
%xyz(dname=dataset_scores.tsv);
%xyz(dname=dataset_income.tsv);
%xyz(dname=dataset.tsv);

Super Contributor
Posts: 704

Re: If then Scan Macro

Posted in reply to novinosrin

No, It did not work either

PROC Star
Posts: 1,605

Re: If then Scan Macro

Please paste the log. Run with options mlogic and mprint and paste the log here. Thanks

PROC Star
Posts: 1,605

Re: If then Scan Macro

Posted in reply to novinosrin

btw you need an AND operator rather than OR:

 

%if (%scan(&dname.,-1,'_') ne scores.tsv and %scan(&dname.,-1,'_') ne income.tsv) %then %do;

Super User
Posts: 13,358

Re: If then Scan Macro

Basic logic problem with "OR" (besides apparently mixing data step and macro code).

If x ne 1 or x ne 2 is ALWAYS true. When x=1 the "ne 2" part is true so you get that selected, if x=2 the first part is true. If either part of an or is true the result is true.

 

 

is this what you were looking for:

%macro xyz(dname=);
data t;
   Length X $15;
   if scan("&dname.",-1,'_') In ( 'scores.tsv' 'income.tsv') then do;
      X='Scores,Income';
   end;
   else do;
      x='Finance Data';
   end;
run;
%mend xyz;
%xyz(dname=dataset_scores.tsv);
%xyz(dname=dataset_income.tsv);
%xyz(dname=dataset.tsv);
Super Contributor
Posts: 704

Re: If then Scan Macro

a comma(,) is not required between values?

 'scores.tsv' 'income.tsv')
?

 

PROC Star
Posts: 1,450

Re: If then Scan Macro

No, the comma is optional.
Trusted Advisor
Posts: 1,831

Re: If then Scan Macro

 

You cannot use %if <cond1> or/and <cond2>.

And you don't need  %if 

%macro xyz(dname=);
data t;
     Length X $15;
     if scan("&dname.",-1,'_') ne 'scores.tsv' and
        scan("&dname.",-1,'_') ne 'income.tsv'  
     then x='Finance Data';
    else X='Scores,Income';
run;
%mend xyz;

%xyz(dname=dataset_scores.tsv);
%xyz(dname=dataset_income.tsv);
%xyz(dname=dataset.tsv);

to do what you want. See next coed:

 

 

PROC Star
Posts: 1,450

Re: If then Scan Macro

@Shmuel what do you mean by "You cannot use %if <cond1> or/and <cond2>"?

 

The macro language understands the operators OR and AND, e.g.:

 

21   %macro ck(cond1,cond2);
22     %put &=cond1 &=cond2;
23     %if &cond1 and &cond2 %then %put %nrstr(&cond1 and &cond2) is True;
24     %else %put %nrstr(&cond1 and &cond2) is False;
25
26     %if &cond1 or &cond2 %then %put %nrstr(&cond1 or &cond2) is True;
27     %else %put %nrstr(&cond1 or &cond2) is False;
28   %mend ck;
29
30   %ck(0,1)
COND1=0 COND2=1
&cond1 and &cond2 is False
&cond1 or &cond2 is True
31   %ck(1,1)
COND1=1 COND2=1
&cond1 and &cond2 is True
&cond1 or &cond2 is True
32   %ck(0,0)
COND1=0 COND2=0
&cond1 and &cond2 is False
&cond1 or &cond2 is False
Trusted Advisor
Posts: 1,831

Re: If then Scan Macro

@Quentin, I'm probably locked on a very old sas version when - %if <cond1> or/and <cond2> - did not work.
Thank you for yor remark.

Super Contributor
Posts: 704

Re: If then Scan Macro

Extendng the logic to drop variables from dataset have.

 This fails.

 

%macro xyz(dname=);
data %scan(&dname.,-2,'.');;
     Length X $15;
set have; if scan("&dname.",-1,'_') ne 'scores.tsv' and scan("&dname.",-1,'_') ne 'income.tsv' then do;
x='Finance Data';
drop var1; else do;
X='Scores,Income';
drop var1 var2; run; %mend xyz; %xyz(dname=dataset_scores.tsv); %xyz(dname=dataset_income.tsv); %xyz(dname=dataset.tsv);

 

PROC Star
Posts: 1,605

Re: If then Scan Macro

I'm afraid drop is a compile time statement and not an executable statement. Therefore you cannot conditionally execute a drop statement. You would have to choose your original idea of the macro where you can generate a drop statement based on  macro if condition.

Trusted Advisor
Posts: 1,831

Re: If then Scan Macro

@SASPhile - your code fail at those two lines:

    then do;        x='Finance Data';drop var1;
    else do;   X='Scores,Income';   drop var1 var2;

1) you miss END to close DO staement.

2) DROP staement cannot be conditional in a data step, it has to be done with macro code:

%macro xyz(dname=);
data t;
     Length X $15;
     if scan("&dname.",-1,'_') ne 'scores.tsv' and
        scan("&dname.",-1,'_') ne 'income.tsv'  
     then x='Finance Data';
     else X='Scores,Income';
     
  %if %scan(&dname, -1, _ ) = %str(Finance Data)
   %then %do; Drop var1; %end;
   %else %do; Drop var1 var2; %end; 

run;
%mend xyz;
Ask a Question
Discussion stats
  • 13 replies
  • 237 views
  • 1 like
  • 5 in conversation