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.
BASUG is hosting free webinars Next up: Jane Eslinger presenting PROC REPORT and the ODS EXCEL destination on Mar 27 at noon ET. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
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
BASUG is hosting free webinars Next up: Jane Eslinger presenting PROC REPORT and the ODS EXCEL destination on Mar 27 at noon ET. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
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;

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

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