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;
Don't miss out on SAS Innovate - Register now for the FREE Livestream!
Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.
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.