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);
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);
No, It did not work either
Please paste the log. Run with options mlogic and mprint and paste the log here. Thanks
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;
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);
a comma(,) is not required between values?
'scores.tsv' 'income.tsv')
?
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:
@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
@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.
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);
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.
@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;
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.