BookmarkSubscribeRSS Feed
tal83
Calcite | Level 5
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);
5 REPLIES 5
sbb
Lapis Lazuli | Level 10 sbb
Lapis Lazuli | Level 10
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
art297
Opal | Level 21
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.
PatrickG
SAS Employee
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.
sbb
Lapis Lazuli | Level 10 sbb
Lapis Lazuli | Level 10
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
chang_y_chung_hotmail_com
Obsidian | Level 7
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 --*;

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

Register now!

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
  • 5 replies
  • 1112 views
  • 0 likes
  • 5 in conversation