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!
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.
I don't see why it wouldn't work, if coded properly.
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.
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?
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.
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 the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.