We’re smarter together. Learn from this collection of community knowledge and add your expertise.

SAS 9.4 Macro Language: Reference Has a New Appendix

by SAS Employee Sue_SAS on ‎08-15-2016 12:00 PM - edited on ‎08-19-2016 08:19 AM by Community Manager (2,052 Views)
Comments
by Super User
on ‎08-15-2016 03:37 PM
by SAS Employee Sue_SAS
on ‎08-15-2016 04:09 PM
Thanks for adding that.


by PROC Star
on ‎08-18-2016 01:12 AM

I just opened Example 15: Delete a File on UNIX or Windows If It Exists

 

It could be much improved by using function fdelete() rather than a system command.

 

This is better because it:

- demonstrates another SAS function

- avoids flashing a terminal window in SAS desktop

- works even if the user has no access to system commands

- simplifies the macro to make it OS-agnostic.

 

Two more comments:

- calling a deletion macro %check() is not good practice

- calling fileexist() again to confirm deletion would show good practice

 

 

 

 

 

 

 

 

 

by PROC Star
on ‎08-18-2016 01:14 AM

Ok, I opened another example: Example 14: Create a Quoted List Separated by Spaces

 

Surely, while what is shown is interesting, the standard method for doing this should be demonstrated as well:

 

proc sql noprint;

select quote(strip(EMPL)) into :list separated by ' ' from ONE;

quit;

 

 

by SAS Employee Sue_SAS
on ‎08-18-2016 10:37 AM

Hey ChrisNZ,

Thanks for the two comments you entered. I've sent your comments to Tech Support.

 

by PROC Star
on ‎08-18-2016 05:11 PM

Thank you for not taking the comments negatively Sue. I was dreading this. :)

by PROC Star
‎08-18-2016 07:05 PM - edited ‎08-18-2016 07:07 PM

Generally speaking, I reckon that SAS-supplied code should be exemplar.

 

It doesn't take much. Consider the code for example 11. Surely this

 

%macro date_loop(start, end, period);
   %local dif i date;
   %let start = %sysfunc(inputn(&start ,anydtdte9. ));
   %let end   = %sysfunc(inputn(&end   ,anydtdte9. ));
   %let dif   = %sysfunc(intck (&period,&start,&end));
   %do i=0 %to &dif;
     %let date=%sysfunc(intnx(&period,&start,&i,b),date9.);
     %put &date;
  %end;
%mend date_loop;

%date_loop(01jul2015, 01feb2016, month)

 

is better than

 


%macro date_loop(start,end);
   %let start=%sysfunc(inputn(&start,anydtdte9.));
   %let end=%sysfunc(inputn(&end,anydtdte9.));
   %let dif=%sysfunc(intck(month,&start,&end));
     %do i=0 %to &dif;
      %let date=%sysfunc(intnx(month,&start,&i,b),date9.);
      %put &date;
     %end;
   %mend date_loop;

   %date_loop(01jul2015,01feb2016)

by SAS Employee Sue_SAS
on ‎08-19-2016 08:08 AM

ChrisNZ,

Please keep the comments coming. I forward them to Tech Support for review.  They are going to use your advice for Example 15. We are changing that one during our next release.

Thanks,

Sue

by PROC Star
on ‎08-19-2016 08:40 AM

Whell, @ChrisNZ you've inspired me.  I glanced at these, rolled my eyes at a few, and looked away.  It's a hard task to write a consistent set of macros, and often the examples I've seen in support notes are not really exemplary (in my eyes), which is understandable as they've been written by a variety of authors over a wide range of time.  But to add a new section of macros to the documentation, I think the quality bar should be higher.

 

Example 10, Retrieve Each Word from a Macro Variable List

 

%let varlist = Age Height Name Sex Weight;

%macro rename;
   %let word_cnt=%sysfunc(countw(&varlist)); 
   %do i = 1 %to &word_cnt; 
     %let temp=%qscan(%bquote(&varlist),&i);
     &temp = _&temp
   %end;
%mend rename;

data new;
   set sashelp.class(rename=(%unquote(%rename)));
run;

The %Rename macro has no parameters defined, the so the parameter is passed as a global macro variable.  Macro vars created in the macro are not declared local.  The macro will choke if given an empty list.   These are basic concepts that are covered into any introductory macro course.

 

 

 

And perhaps this is a style choice, but I wouldn't worry about %quoting the var names and %unquoting  them during the macro incvocation.  Because I don't use special characters in var names. So I would use something like:

 

%macro rename(varlist=);
   %local i var;
   %do i = 1 %to %sysfunc(countw(&varlist,%str( ))); 
     %let var=%scan(&varlist,&i,%str( ));
     &var = _&var
   %end;
%mend rename;

data new;
   set sashelp.class(rename=( %rename(varlist=Age Height Name Sex Weight) ));
run;

 

I suppose if your really want the quoting could use:

 

%macro rename(varlist=);
   %local i var;
   %do i = 1 %to %sysfunc(countw(%bquote(&varlist),%str( ))); 
     %let var=%qscan(%bquote(&varlist),&i,%str( ));
     %unquote(&var) = _%unquote(&var)
   %end;
%mend rename;

data new;
   set sashelp.class(rename=( %rename(varlist=Age Height Name Sex Weight) ));
run;

 

That would at least hide the unquoting from the user.

 

Of course as with any macro, you could add more parameters (for the delimiter, etc), and add functionality.  I'm fine with the documentation including "basic" macros.  But it's important that even in such "simple" macros, best practices are illustrated and explained.

by SAS Employee Sue_SAS
on ‎10-19-2017 01:07 PM

Hey ChrisNZ,

 

Example 15 has been updated and will be in the next SAS release. Thanks again for the comments.

 

Sue

 

Your turn
Sign In!

Want to write an article? Sign in with your profile.


Looking for the Ask the Expert series? Find it in its new home: communities.sas.com/askexpert.