DATA Step, Macro, Functions and more

macros.. basic

Reply
Contributor
Posts: 30

macros.. basic

Hi ,
I'm trying to write a macro that will include a "call symput" part.
I have a data set of 1 observation , that has the following variables:
intercept, &var1 and &var2.
I want to assign 3 macro variables:
intercept21
var1
var2
that will store these values.
How can I do it?

Thanks!



%macro reg_fill(indat,var1,var2,stat_id);
data _null_; set &indat;
call symput ("Intercept&stat_id.",Intercept);
call symput ("&var1.",&var1);
call symput ("&var2.",&var2);
run;
%put &var1. &var2.;
%mend reg_fill;

%reg_fill(data,O3,NOx,21);
Super Contributor
Super Contributor
Posts: 3,174

Re: macros.. basic

Presuming your SAS input file WORK.DATA has the proper SAS variables (INTERCEPT21, O3, NOX, as you have listed in the macro invocation command), your SAS program should work as coded. Did you try to execute the code? If yes, then what happened - or what error did you receive? Suggest you paste any SAS log in a forum reply.

Also, you will want to use this SAS statement for additional macro debugging:

OPTIONS SOURCE SOURCE2 MACROGEN SYMBOLGEN /* MLOGIC */ MPRINT;



Scott Barry
SBBWorks, Inc.

Suggested Google advanced search argument, this topic / post:

MACRO VARIABLE SCOPE site:sas.com
PROC Star
Posts: 7,474

Re: macros.. basic

I'm not sure what you are trying to do but, if you are trying to use those macro variables outside of the macro, you may have to define them to be global macro variables. Does the following do what you expected to get:


%macro reg_fill(indat,var1,var2,stat_id);
%global Intercept&stat_id. &var1. &var2.;
data _null_; set &indat;
call symput ("Intercept&stat_id.",Intercept);
call symput ("&var1.",&var1);
call symput ("&var2.",&var2);
run;
%put &var1. &var2. &O3. &NOx.;
%mend reg_fill;
data data;
input Intercept (O3 NOx) ($);
cards;
0 A B
;
run;
%reg_fill(data,O3,NOx,21)
%put &Intercept21. &O3. &NOx.;

Art

p.s. Leave the semi-colon off of the line where you call the macro, as it is redundant and could end causing a problem itself.
SAS Employee
Posts: 58

Re: macros.. basic

When I run his code, the %put statement works because he's passing in the values for &var1 and &var2 as arguments to the macro, so use of the call symput is irrelevent w.r.t. the macro.

That being said, any other attempts to %put the values of &var1 and &var2 in open code won't work. It's a timing thing. The call symput does its thing during execute time, but all of the macro statements in open code are evaluated during compile time.
Super Contributor
Super Contributor
Posts: 3,174

Re: macros.. basic

Not exactly true, the RUN; statement's position is key to the compilation processing sequence.

By the way, my post mentioned INTERCEPT21 (as a SAS variable in WORK.DATA) and it should mention INTERCEPT. Of course, the OP mentions the SAS file has the variables resolved / identified as argument #2 to the CALL SYMPUT invocation.

So, the key issue here is MACRO VARIABLE SCOPE -- that being either LOCAL or GLOBAL. And with the CALL SYMPUT being generated from within the macro itself, and not having a %GLOBAL definition, as mentioned by art297, these SAS macro variables will only be accessible / resolved from within the macro execution itself and not in open-code.

By having the RUN; statement coded, SAS stops to compile the DATA step and then continues. So, had the OP coded the statement below, the macro variable INTERCEPT21 would be resolved as a local macro variable:

%put &&intercept&stat_id ;

Scott Barry
SBBWorks, Inc.

Suggested Google advanced search argument, this topic / post:

MACRO VARIABLE SCOPE site:sas.com
Regular Contributor
Posts: 241

Re: macros.. basic

Here is a sketch of a method which is a bit beyond basics. This can be used to retrieve a variable's value. The first call will open the data set and a later call with an out-of-range observation number will close it. If any problems, then it will (probably) return nothing. Hope this helps a bit.



   %macro getValueOf(var, data=_last_, obsno=1);


     %global getValueOf_ds;


     %local rc;


     %if &getValueOf_ds= %then %do;


       %let getValueOf_ds=%sysfunc(open(&data,i));


       %if &getValueOf_ds=0 %then %goto cleanUp;


     %end;


     %syscall set(getValueOf_ds);


     %let rc = %sysfunc(fetchobs(&getValueOf_ds, &obsno));


     %if &rc ^= 0 %then %goto cleanUp;


     %*;&&&var


     %return;


   %cleanUp:


     %if &getValueOf_ds>0 %then %let rc = %sysfunc(close(&getValueOf_ds));


     %symdel getValueOf_ds;


   %mend  getValueOf;


 


 


   /* checking */


   data class;


     set sashelp.class(obs=1);


   run;


 


   %put name=%getValueOf(name);


   %put age =%getValueOf(age);


   %*-- on log


   name=Alfred


   age =14


   --*;


   %getValueOf(obsno=0) %*-- to close the data set --*;

Ask a Question
Discussion stats
  • 5 replies
  • 148 views
  • 0 likes
  • 5 in conversation