BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
KHKrishna
Calcite | Level 5

Hi sas support community  i am very poor in sas macros can anyone sugest how improve macro coding?

9502404240
1 ACCEPTED SOLUTION

Accepted Solutions
PabloNogueras
Obsidian | Level 7

My fun answer of the day:  Find Ron Fehd, spend a whole week with him, and you, too will become a Macro Expert.

 

Smiley Very Happy

View solution in original post

8 REPLIES 8
PeterClemmensen
Tourmaline | Level 20

Hi and welcome to the SAS Communities 🙂

 

Lots of learning material out there. But the best is probably the Documentation itself:

 

Getting Started with the Macro Facility

tomrvincent
Rhodochrosite | Level 12
Keep it simple. The first step should be getting one simple macro working and then expanding it from there.

Start with something that has no variables at all and then add one...keep building from there, growing your comfort as you go.
Kurt_Bremser
Super User

The first (and really essential, important and absolutely necessary) step in good macro coding: achieve proficiency in coding without using macros.

The macro preprocessor is a code generator, and you'll only be able to use it properly when you have very good knowledge of the code you will be creating with the macro.

And very often you will find that proper knowledge of the non-macro tools leads to the gist of Maxim 11: A Macro is not Needed.

 

90% of the problems with macros we encounter here on the communities comes from premature tinkering with macros and trying to solve data issues with the wrong tool.

Reeza
Super User

As others have indicated, macros should be a last resort. 

 

Assuming you already know the following well:

  • BY group processing
  • data step processing (with output)
  • arrays
  • procs such as : freq, means (class, ways and types statements are powerful), freq, transpose, tabulate and report

Some good resources:

https://stats.idre.ucla.edu/sas/seminars/sas-macros-introduction/

 

Macro appendix, in the documentation has a set of good examples:

https://communities.sas.com/t5/SAS-Communities-Library/SAS-9-4-Macro-Language-Reference-Has-a-New-Ap...

 

My short tutorial on creating a macro:

https://github.com/statgeek/SAS-Tutorials/blob/master/Turning%20a%20program%20into%20a%20macro.md

 

One general premise of writing a macro - first make sure you have working code that solves the situation for a base case and then generalize it. If you skip this step, you run the risk of spending hours debugging.

gamotte
Rhodochrosite | Level 12

Hello,

 

You can execute the following program and read the log to have an illustration of

the main concepts of SAS macro programming.

 

/* Macro quick tutorial */

/* Note: SAS macros are used to generate SAS code and should not be used for processing data */

options mprint mlogic symbolgen; /* Add useful informations in the log */

%let mv=10; /* a macro variable is initialized with %let */

/* &<macrovariable>. is replaced at compile time by its value */

%put &mv.; /* 10 displayed in the log */

data ds&mv.; /* data ds10; */
    set sashelp.class;
run;

%let mv2=&mv.+1; /* 10+1 not 11  => only text substition */

%put &mv2.; /* 10+1 displayed in the log */

data ds&mv2.; /* data ds10+1; => ERROR */
    set sashelp.class;
run;

%let mv3=%eval(&mv.+1); /* 11 */

%put &mv3.;

/* A macro variable can hold the name of another macro variable */
%let x=5;
%let mvname=x;

/* During the resolution, two consecutive ampersands are resolved in a single ampersand */
%put &mvname.;   /* x */
%put &&mvname.;  /* x ((&&)mvname. => &mvname. => x) */
%put &&&mvname.; /* 5 ((&&)(&mvname.) => &x. => 5)*/

data _NULL_;
    set sashelp.class;
    /* Creates a macrovariable from a dataset column    */
    /* The instruction is executed for each row of data */
    call symputx("name", name);

    %put &name.; /* &name. will only be available at the end of the datastep   */
                 /* => WARNING if the macrovariable does not exist previous to */
                 /* the data step                                              */
                 /* otherwise, its value before the data step.                 */
run;

%put &name.; /* William (last observation of sashelp.class) */

data _NULL_;
    set sashelp.class;
    call symputx(cats("name",_N_), name);
run;

%put &name1. &name2. &name3.; /* Alice Barbara Carol */

/* Affectation of macrovariables to dataset columns */
data macro;
    length will name $32.;

    will=symget("name");             /* William */
    will2="&name.";                  /* William */
    will3='&name.';                  /* &name. => no resolution with single quotes */
    x=symgetn("x");                  /* 5 */

    do _N_=1 to countw("&names.");
        name=symget(cats("name",_N_));   /* Alice, Barbara, Carol, ... William */
        output;
    end;
run;

/* Create macrovariables from dataset columns with proc sql */
proc sql noprint;
    SELECT name, name
    INTO :name, :names SEPARATED BY ' '
    FROM sashelp.class;
quit;

%put &name.; /* Alice */
%put &names.; /* Alice Barbara Carol ... Thomas William */

/* Macro functions are necessary for conditional branching, loops   */
/* They can be used for repetitive tasks to avoid replicating large */
/* chunks of code.                                                  */
%macro f(pos, kw=default, kw2=);
    /* pos : positional argument                                        */
    /* kw, kw2 : keyword parameters                                     */
    /* positional parameters must apperar before keyword parameters     */

    %if &pos.=1 %then %do;
        %put OK;
    %end;
    %else %do;
        %put KO;
    %end;

    %put &kw. &kw2;

%mend; /* end of the macro function definition */

%f(1)            /* OK default       */
%f(2, kw2=hello) /* KO default hello */
%f(2, kw=foo)    /* KO foo */
%f(kw=bar)       /* KO bar */
%f(kw=bar,pos=0) /* KO bar => positional parameters can also be called by name */

/* Usage of macro loops */
%macro f2(ds, out);

    %do i=1 %to 5;
        data &out.&i.;
            row=&i.;
            set &ds. point=row;
            output; stop;
        run;

        /* Loops can be used to create indexed macrovariables */
        %let x&i.=&i.; /* x1=1, x2=2, ..., x5=5 */

        %put &&x&i.; /* 1, 2, 3, 4, 5 ((&&)(x&i). => &x1. => 1 */
    %end;

%mend;

%f2(sashelp.class, student) /* datasets student1 (Alice), student2 (Barbara) */

/* Scope */

%let j=1; /* defined outside macro => global scope */

%macro a;

    %do i=1 %to 5;
        %put &i.;
    %end;

%mend;

%macro main;

    /* The same counter name (i) is used in macro main and macro a */
    %do i=1 %to 2;
        %a;
    %end;

    %let j=2; /* Modifies the global macro variable j */

%mend;

%main /* 1 2 3 4 5 (the value of i in macro a replaced the one computed in macro main) */
      /* => Only one iteration of the loop in main                                     */

%put &j.; /* 2 (modified by the macro) */

%macro b;

    %local i; /* i is now a macrovariable specific to the macro b */ 

    %do i=1 %to 5;
        %put &i.;
    %end;

%mend;

%macro main2;

    %local j;

    %do i=1 %to 2;
        %b;
    %end;

    %let j=5;

%mend;

%main2 /* 1 2 3 4 5 1 2 3 4 5 */

%put &j.; /* 2 (the global variable value has not been replaced) */

Edit : Added @Tom example of macro call with names positional argument.

Tom
Super User Tom
Super User

I would add an example in your block of example macro calls where you call the positional parameter by name.   That is a very nice usability feature of SAS macro calls that other languages often lack.

 

%f(kw=bar,pos=0)       /* KO bar */
gamotte
Rhodochrosite | Level 12
Done, thanks.
PabloNogueras
Obsidian | Level 7

My fun answer of the day:  Find Ron Fehd, spend a whole week with him, and you, too will become a Macro Expert.

 

Smiley Very Happy

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
How to Concatenate Values

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 8 replies
  • 1776 views
  • 15 likes
  • 8 in conversation