BookmarkSubscribeRSS Feed
SASPhile
Quartz | Level 8

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);

13 REPLIES 13
novinosrin
Tourmaline | Level 20

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);

SASPhile
Quartz | Level 8

No, It did not work either

novinosrin
Tourmaline | Level 20

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

novinosrin
Tourmaline | Level 20

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;

ballardw
Super User

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);
SASPhile
Quartz | Level 8

a comma(,) is not required between values?

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

 

Quentin
Super User
No, the comma is optional.
Shmuel
Garnet | Level 18

 

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:

 

 

Quentin
Super User

@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
Shmuel
Garnet | Level 18

@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.

SASPhile
Quartz | Level 8

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);

 

novinosrin
Tourmaline | Level 20

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.

Shmuel
Garnet | Level 18

@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;
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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 13 replies
  • 3062 views
  • 1 like
  • 5 in conversation