I have the following scenario. I am want to use multiple 'sex ' criteria to subset the data. Is it possible? what's the best way to achieve it to control sub setting conditions. In the below example I want flexibility where I can enter one or two observation for &sex macro variable. Thanks
%macro filter(sex= );
data class;
set sashelp.class;
if upcase(sex) in ( "&sex");
*if upcase (sex) in ('F' 'M'); *how to achieve this using macro variable:
run;
%mend;
%filter( sex= F );
%*filter ( sex = %nrbquote('F' 'M'));*I wanna use like this or any other alternatives to call macro;
Since you mentioned flexibility, an alternate design would be to allow the user to pass any subsetting expression, not just values to allow subsetting by gender. Sometimes I do stuff like:
%macro filter(where=1 );
data class;
set sashelp.class;
where &where;
run;
proc print data=class ;
run ;
%mend;
%filter()
%filter(where=(sex='F') )
%filter(where=(sex IN ('F','M')) ) /*this comma is not a problem because the parentheses mask it*/
%filter(where=(age<15))
%filter(where=(Name =: 'J' and age<=13))
For a utility macro that is designed to be used by a SAS programmer, I find the flexibility of allowing them to provide any valid WHERE clause is often valuable.
Try FINDW() function:
%macro filter(sex= ); data class; set sashelp.class; if findw("&sex",strip(upcase(sex))); run; %mend; %filter ( sex =F M )
@SASuserlot wrote:
I have the following scenario. I am want to use multiple 'sex ' criteria to subset the data. Is it possible? what's the best way to achieve it to control sub setting conditions. In the below example I want flexibility where I can enter one or two observation for &sex macro variable. Thanks
%macro filter(sex= ); data class; set sashelp.class; if upcase(sex) in ( "&sex"); *if upcase (sex) in ('F' 'M'); *how to achieve this using macro variable: run; %mend; %filter( sex= F ); %*filter ( sex = %nrbquote('F' 'M'));*I wanna use like this or any other alternatives to call macro;
Remember that when you execute code that contains macros and macro variables, the values of the macro variables are used in place of the actual macro variable to generate code. Your macro above would, when executed, produce this code:
if upcase(sex) in ( "'F' 'M'");
this will not match the sex values in SASHELP.CLASS which are 'F' or 'M', it will match a record if the value of sex is "'F' 'M'", but there is no such record that has this value for sex. So you really need to "envision" what the code generated by the macro will be. Hence, when @Astounding tells you that you should remove the double quotes around &sex and use %filter (sex = 'F' 'M'), then this will produce the line of code
if upcase(sex) in ( 'F' 'M');
which is what you really want.
In addition, you could turn on macro debugging options
options mprint;
before you run your macro, and then you can see in the log that the code generated is not what you want it to be:
MPRINT(FILTER): data class; MPRINT(FILTER): set sashelp.class; MPRINT(FILTER): if upcase(sex) in ( "'F' 'M'"); MPRINT(FILTER): run;
Since you mentioned flexibility, an alternate design would be to allow the user to pass any subsetting expression, not just values to allow subsetting by gender. Sometimes I do stuff like:
%macro filter(where=1 );
data class;
set sashelp.class;
where &where;
run;
proc print data=class ;
run ;
%mend;
%filter()
%filter(where=(sex='F') )
%filter(where=(sex IN ('F','M')) ) /*this comma is not a problem because the parentheses mask it*/
%filter(where=(age<15))
%filter(where=(Name =: 'J' and age<=13))
For a utility macro that is designed to be used by a SAS programmer, I find the flexibility of allowing them to provide any valid WHERE clause is often valuable.
Thank you @Quentin providing me the flexible options.
Thank you every one who provided the different ways to achieve the solutions. I really appreciate taking your time to answer this and providing insights how to use the code more useful way.
Thank you @PaigeMiller @Astounding @Ksharp @Quentin .
Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!
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.
Ready to level-up your skills? Choose your own adventure.