Raising Abstraction Level in SAS

by

in

In the following codes an attempt is made to raise the abstraction level available to the sas programmer by providing list manipulation macros:


/**
* List manipulation macros :
* The first 9 macros are used for the manipulation of lists.
*/
/**
* Everywhere in this code list will refer to space separated words stored in a macro variable
* These have been used extensively in this program.
*
* eg usage of a list
* %let MacroVariable_To_Store_List = ListElement1 ListElement2 ListElement3 ListElement4;
* Then
* %scan(&MacroVariable_To_Store_List, 3, %str( ))
* will return ListElement3
*/
/**
* The macro returns the number of words in the list given as the parameter – VariableList
*/
%macro LengthOfList(VariableList);
%let i = 1;
%do %while(%scan(&VariableList, &i, %str( )) ne %str());
%let i = %eval(&i + 1);
%end;
%eval(&i – 1)
%mend LengthOfList;
/**
* The macro returns a new list from a list (given as the first parameter- VariableList)
* with one word deleted (which is the second parameter – VarToBeRemoved)
*/
%macro DeleteOneFromList(VariableList,VarToBeRemoved);
%let i = 1;
%do %while(%scan(&VariableList, &i, %str( )) ne %str());
%let var = %scan(&VariableList, &i, %str( ));
%if %index(&var,&VarToBeRemoved) = 0 %then &var;
%let i = %eval(&i + 1);
%end;
%mend DeleteOneFromList;
/**
* The macro returns a new list from a list (given as the first parameter – VariableList) with a
* specified list of words deleted (which is the second parameter – ListOfVarsToBeRemoved)
*/
%macro DeleteFromList(VariableList,ListOfVarsToBeRemoved);
%let outer = 1;
%do %while(%scan(&ListOfVarsToBeRemoved, &outer, %str( )) ne %str());
%let TempList = ;
%let varO = %scan(&ListOfVarsToBeRemoved, &outer, %str( ));
%let inner = 1;
%do %while(%scan(&VariableList, &inner, %str( )) ne %str());
%let varI = %scan(&VariableList, &inner, %str( ));
%if &varO ne &varI
%then %let TempList = &TempList &varI;
%let inner = %eval(&inner + 1);
%end;
%let VariableList = &TempList;
%let outer = %eval(&outer + 1);
%end;
&VariableList
%mend DeleteFromList;
/**
* The macro checks whether a particular macro variable (given as the parameter Macrovar) already exists
* or not
*/
%macro CheckExistenceOfMacroVar(Macrovar);
%* Taken from the publicly available code sample by DeVenezia
%* Richard A. DeVenezia 12/23/98;
%* macrovar – name of macro variable to check for existence;
%* emits
%* 0 if macro variable is not found in SASHELP.VMACRO;
%* 1 if macro variable is found in SASHELP.VMACRO;
%* -1 if an error occurred;
%* Note: if option NOTES and the macro variable is not found in
%* SASHELP.VMACRO by the where clause of the open statement
%* there will be a note in the log
%* NOTE: No observations were selected from data set SASHELP.VMACRO.
%* There is currently no way to circumvent this.
%*;
%local dsid;
%let dsid = %sysfunc (open (SASHELP.VMACRO (where=(name=upcase("&macrovar") and scope ne "EXISTMV"))));
%if &dsid %then %do;
%sysfunc (attrn (&dsid, ANY))
%let dsid = %sysfunc (close (&dsid));
%end;
%else %do;
-1
%end;
%mend CheckExistenceOfMacroVar;
/**
* From macrovariables – MacroVarsPrefix_1 … MacroVarsPrefix_n this macro returns a list which has
* values stored in the individual macro variables.
* It checks the existence of n-th macro variable and if it exists adds it to the list
*/
%macro CreateOneListFromMacroVars(MacroVarsPrefix);
%let listab = ;
%let i = 1;
%do %while(%CheckExistenceOfMacroVar(&MacroVarsPrefix&i) = 1);
%let listab = &listab &&&MacroVarsPrefix.&i;
%if &i > 1000
%then %do;
%put ERROR: In CreateOneListFromMacroVars Macro ;
%goto exit;
%end;
%let i = %eval(&i + 1);
%end;
&listab
%exit:
%mend CreateOneListFromMacroVars;
/**
* (Same as above except that it stops at the value of n corresponding to the input parameter – UntilIndex. )
* From macrovariables – MacroVarsPrefix_1 … MacroVarsPrefix_UntilIndex this macro returns a
* list which has values stored in the individual macro variables.
*/
%macro CreateOneListFromMacroVars2(MacroVarsPrefix, UntilIndex);
%let listab = ;
%let i = 1;
%do %while(&i le &UntilIndex);
%if %CheckExistenceOfMacroVar(&MacroVarsPrefix&i) = 1
%then %do;
%let listab = &listab &&&MacroVarsPrefix.&i;
%if &i > 1000
%then %do;
%put ERROR: In CreateOneListFromMacroVars2 Macro ;
%goto exit;
%end;
%end;
%else %do;
%put ERROR: In CreateOneListFromMacroVars2 Macro ;
%put Atleast one MacroVariable from which list is to be created does not exist ;
%goto exit;
%end;
%let i = %eval(&i + 1);
%end;
&listab
%exit:
%mend CreateOneListFromMacroVars2;
/**
* To each of the words in the input list (given as a parameter VariableList) it adds a prefix
* eg if macro variable InputList has value – word1 word2 word3
* then %AddPrefixToVarsInList(&InputList, Prefix)
* returns
* Prefixword1 Prefixword2 Prefixword3
*/
%macro AddPrefixToVarsInList(VariableList, Prefix);
%let i = 1;
%do %while(%scan(&VariableList, &i, %str( )) ne %str());
%let var = %scan(&VariableList, &i, %str( ));
&Prefix&var
%let i = %eval(&i + 1);
%end;
%mend AddPrefixToVarsInList;
/**
* Same as above except that it adds the second parameter as a suffix to each of the word in the inputlist
*/
%macro AddSuffixToVarsInList(VariableList, Suffix);
%let si = 1;
%do %while(%scan(&VariableList, &si, %str( )) ne %str());
%let var = %scan(&VariableList, &si, %str( ));
&var&Suffix
%let si = %eval(&si + 1);
%end;
%mend AddSuffixToVarsInList;
%macro AddPrefixToVarsInList(PrefixVariableList, Prefix);
%let PrefixIterator = 1;
%do %while(%scan(&PrefixVariableList., &PrefixIterator., %str( )) ne %str());
%let var = %scan(&PrefixVariableList., &PrefixIterator., %str( ));
&Prefix.&var.
%let PrefixIterator = %eval(&PrefixIterator. + 1);
%end;
%mend AddPrefixToVarsInList;
%macro AddSuffixToVarsInList(SuffixVariableList, Suffix);
%let SuffixIterator = 1;
%do %while(%scan(&SuffixVariableList., &SuffixIterator., %str( )) ne %str());
%let var = %scan(&SuffixVariableList., &SuffixIterator., %str( ));
&var.&Suffix.
%let SuffixIterator = %eval(&SuffixIterator. + 1);
%end;
%mend AddSuffixToVarsInList;
/**
* Combination of the two above, adds prefix and suffix to each of the words in the list in one step
*/
%macro AddPrefandSufToVarsInList(VariableList, Prefix, Suffix);
%let si = 1;
%do %while(%scan(&VariableList, &si, %str( )) ne %str());
%let var = %scan(&VariableList, &si, %str( ));
&Prefix.&var.&Suffix
%let si = %eval(&si + 1);
%end;
%mend AddPrefandSufToVarsInList;
/*List manipulation macros End*/

 

 

Discover more from Gaurav Sharma's Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading