Help using Base SAS procedures

How to find a match among different macro lists

Accepted Solution Solved
Reply
Highlighted
Contributor gsk
Contributor
Posts: 25
Accepted Solution

How to find a match among different macro lists

I have: 

&numlist, which has a list of numeric variables in a dataset
&datelist, which has a list of date variables in a dataset 
&charlist, which has a list of character variables in a dataset

&varordered, which has a list of all numeric, date, character variables of a dataset in alphabetical order. 

%macro numsum: summarizes a list of numeric variables 

%macro charsum: summarizes a list of character variables

%macro datesum: summarizes a list of date variables 

 

I want to make a macro function that takes in &varordered and runs one of the three macro functions according to the variable type of the variables in the &varordered list. I'm doing this because I want to produce a summary output of every variable alphabetically. 

 

I'm worried if taking in a list of num/char/date variables would be a problem though, since I would be feeding in one variable at a time, not a list of num/char/date, from &varordered.  

 

To sketch the idea, I think this form would work for the macro? 
%macro (allvar= &varordered); 
          %let i=1;
          %do %until (%scan(&allvar,&i)= );

          %let var=%scan(&allvar,&i);
                    /* Here, I want to do: */
                    /* if the scanned variable in allvar is numeric (in &numlist), run a macro function called numsum */
                    /* if the scanned variable in allvar is character (in &charlist), run a macro function called charsum */
                    /* if the scanned variable in allvar is a date variable (in &datelist), run a macro function called datesum */
          %end; 
%mend allvar ;

 

 

 

*************************************;

Code for one of the three macro functions I have fyi: 

 

%macro charsum;
          %let i=1;

          %do %until (%scan(&charlist,&i)= );

          %let var=%scan(&charlist,&i);

          proc sql noprint;
                    select count (distinct &var) into :valcount
                    from met.dema_669;
          quit;

 

          %if &valcount<=6 %then %do;
                    proc freq data=met.dema_669;
                              tables &var / missing;
                              title "Frequency table for &var";
                    run;
          %end;

 

          %else %do;
                    data _null_;
                              file print; 
                              length sentence $200; 
                              sentence="Variable &var is not tabulated; all or most values unique";
                              put sentence; 
                              put _page_; 
                    %end; 
                    title;
          %let i= %eval(&i+1);
          %end;
%mend charsum;

 

 

Thank you for the help in advance! 

 


Accepted Solutions
Solution
‎04-15-2018 09:20 PM
Super User
Posts: 6,903

Re: How to find a match among different macro lists

The exterior macro has already identified the next name to process as &VAR.  Here's one way to search:

 

%if %sysfunc(findw(&numlist, &var)) %then %do;

 

If for any reason you want to stick to purely macro language functions, it can be done but is clumsy:

 

%if %index(%str( &numlist ), %str( &var )) %then %do;

 

The leading and trailing blanks are now treated as significant characters, a requirement for the proper result.  You don't want the search for VAR1 to locate a match if the software finds VAR11.

View solution in original post


All Replies
Respected Advisor
Posts: 3,251

Re: How to find a match among different macro lists

I don't see why it wouldn't work, if coded properly. 

--
Paige Miller
Super User
Posts: 6,903

Re: How to find a match among different macro lists

So far, you have established four infinite loops.  I would fix those before worrying about the step that you posted.

 

The new macro you are asking for needs to increment &i, just as you have done in your earlier macros:

 

%let i = %eval(&i + 1);

 

Without incrementing &i, the new macro runs forever.

 

And each of your existing macros needs to add this as the first statement:

 

%local i;

 

Without that, your existing 3 macros will use the same &i as the new macro, and will re-set &i to 1 repeatedly.

 

All of that is necessary just to be able to safely test any proposed code.  You will also need to deal with the fact that your existing macros look to process all variables in a list, not just a single variable.  So you need to modify your existing macros so that they will process just a single variable at a time.  

 

With those steps in place, the programming can begin on your request.

Contributor gsk
Contributor
Posts: 25

Re: How to find a match among different macro lists

Posted in reply to Astounding

Thank you, I've changed the three macros to take in one variable only (by deleting the loops) and because of that, they don't have i anymore.

And yes, I forgot to add %eval(&i+1) and have added that line at the end of the macro I want to make.  

 

Now, how do we check if a scanned variable in &allvar is in any of &numlist/&charlist/&datelist and run one of the macro functions numsum/charsum/datesum accordingly?

Solution
‎04-15-2018 09:20 PM
Super User
Posts: 6,903

Re: How to find a match among different macro lists

The exterior macro has already identified the next name to process as &VAR.  Here's one way to search:

 

%if %sysfunc(findw(&numlist, &var)) %then %do;

 

If for any reason you want to stick to purely macro language functions, it can be done but is clumsy:

 

%if %index(%str( &numlist ), %str( &var )) %then %do;

 

The leading and trailing blanks are now treated as significant characters, a requirement for the proper result.  You don't want the search for VAR1 to locate a match if the software finds VAR11.

☑ This topic is solved.

Need further help from the community? Please ask a new question.

Discussion stats
  • 4 replies
  • 177 views
  • 1 like
  • 3 in conversation