1

I've got a macro with three parameters

%mymac(name,color,pet);

I've got a dataset with three variables NameX, ColorX, and Petx and 20 records how would I run the macro, once for each record in the dataset, passing the three fields in as parameters for example:

%mymac(name='mike', color='blue',pet='dog'); 
%mymac(name='eve',color='orange',pet='cat');
flag

3 Answers

2

There are a number of doing this in SAS.

1) The CALL EXECUTE strategy is good. However, you should be aware that CALL EXECUTE can behave oddly at times. Be VERY careful about the use of RUN in all PROC and DATA steps inside the macro being CALL EXECUTE-processed.

2) When writing the CALL EXECUTE statement, I NEVER just put the variable name, which allows SAS to convert numeric variables into character. I ALWAYS format variables.

It is much better to do something like some have suggested but improved slightly:

DATA _NULL_;
     SET SOURCE;
     STRNG=CATS('%_mymac(_a="' , TRIM(LEFT(STRA)), '",_b=' , 
                TRIM(LEFT(PUT(HEIGHT,4.1))) , ');');
     CALL EXECUTE(STRNG);
RUN;

Using the explicit PUT statement ensures that you control the exact formatting, not SAS. Default formats can be problematical.

2) Many persons have suggested ALWAYS enclosing the CALL EXECUTE information in a %nrstr to ensure that the timing of the CALL EXECUTE process is correct.

DATA _NULL_;
     SET SOURCE;
     STRNG=CATS('%_mymac(_a="' , TRIM(LEFT(STRA)), '",_b=' , 
                TRIM(LEFT(PUT(HEIGHT,4.1))) , ');');
     CALL EXECUTE(%nrstr(STRNG));
RUN;

4) Writing out macro calls to a file can work too, but is clunky. It does give you the opportunity of looking at the macro code, which can be useful at times.

5) You can use "macro arrays". Here is a sketch:

%macro _iter;
DATA _NULL_;
     SET SOURCE;
     RETAIN CX 0;
     CX+1;
     VX=COMPRESS(PUT(CX,3.));
     CALL SYMPUT("_pxa"||VX,TRIM(LEFT(NAME)));
     CALL SYMPUT("_pxb"||VX,TRIM(LEFT(PUT(HEIGHT,5.1))));
     CALL SYMPUT("_cx",VX);
RUN;

%do _i=1 %to &_cx;
%_mymac(_name=&&_pxa&_i,_height=&&_pxb&_i)
%end;
%mend _iter;

%_iter

These are embedded in a macro, since macro loops cannot run in plain code. The use of the TRIM and LEFT commands removes leading and trailing blanks, which are usually not an issue but can become a problem sometimes. It's a little trouble, but only a little.

6) With a small amount of work writing arrays, the CALL SYMPUT commands can be set up as arrays to process up an unlimited number of variables.

link|flag
4

Use call execute()...

data _null_ ;
  set ds ;
  cmd = cats('%mymac(name="' , namex , '",color="' , colorx , '",pet="' , petx , '");') ;
  call execute(cmd) ;
run ;
link|flag
3

What you can do is in your data step, write out the macro calls to a file, then include the file. Something like:

data _Null_;
set ds;
file 'temp.inc';
put '%mymac(name="' name '", color="' color '",pet="' pet '");';
run;

%include 'temp.inc';
link|flag

Your Answer

Not the answer you're looking for? Browse other questions tagged or ask your own question.