Desktop productivity for business analysts and programmers

Issue with assigning a macro variable in a data step

Accepted Solution Solved
Reply
Occasional Contributor
Posts: 6
Accepted Solution

Issue with assigning a macro variable in a data step

[ Edited ]

While playing around with loops in data sets and assinging macro variables with SYMPUT, I stumbled accross an issue, where SAS doesn't do what I would expect it to do.

 

I want to use a loop within a data set and assign the incrementer to a macro variable. I personally never believed this could be an issue. However, SAS ...

 

A simple example is as follows:

 

[CODE1]

%let x = 1;
data _NULL_;
	do i = 1 to 5;
		call symput('x', i);
		put "x now is &x. and i is " i;
	end;
run;

 

[OUTPUT1]

x now is 1 and i is 1
x now is 1 and i is 2
x now is 1 and i is 3
x now is 1 and i is 4
x now is 1 and i is 5

 

Am I so **bleep** stupid to assume that the following output would be reasonable?:

[OUTPUT1*]

x now is 1 and i is 1
x now is 2 and i is 2
x now is 3 and i is 3
x now is 4 and i is 4
x now is 5 and i is 5

 

OK. I was then thinking that maybe the %let statement at the beginning somehow overrules everything and I would have to remove it. So, I did that:

 

[CODE2]

data _NULL_;
	do i = 1 to 5;
		call symput('x', i);
		put "x now is &x. and i is " i;
	end;
run;

What would you expect now?

 

Don't tell me you would expect this:

 

[OUTPUT2]

x now is            5 and i is 1
x now is            5 and i is 2
x now is            5 and i is 3
x now is            5 and i is 4
x now is            5 and i is 5

 

 

The different space, 5, .... I mean, I cannot even imagine why they made it that way... :-)

 

Can someone please help me?


Accepted Solutions
Solution
‎01-18-2017 12:04 PM
Respected Advisor
Posts: 4,989

Re: Issue with assinging a macro variable in a data step

The software needs to compile the DATA step, then run it.  That means the contents of the PUT statement do not change as the DATA step executes.  The value of &X before the DATA step begins is the one that is used within the PUT statement.

 

The second DATA step says that &X is 5, because you ran the steps as part of the same program.  As the first DATA step begins, &X is 1.  So the PUT messages reflect that.  Once the first DATA step is over, &X is 5.  So when the second DATA step gets compiled, that's the value that becomes part of the PUT statement.

View solution in original post


All Replies
Solution
‎01-18-2017 12:04 PM
Respected Advisor
Posts: 4,989

Re: Issue with assinging a macro variable in a data step

The software needs to compile the DATA step, then run it.  That means the contents of the PUT statement do not change as the DATA step executes.  The value of &X before the DATA step begins is the one that is used within the PUT statement.

 

The second DATA step says that &X is 5, because you ran the steps as part of the same program.  As the first DATA step begins, &X is 1.  So the PUT messages reflect that.  Once the first DATA step is over, &X is 5.  So when the second DATA step gets compiled, that's the value that becomes part of the PUT statement.

New Contributor
Posts: 4

Re: Issue with assinging a macro variable in a data step

Hi Andreas,

 

call symput only writes to the macro symbol table once the data step finishes processing. If you trace through your code execution with that knowledge, you'll find that the behaviour you're seeing is valid and predictable.

 

Cheers,

 

Andy.

Super Contributor
Posts: 284

Re: Issue with assinging a macro variable in a data step

I think a segment of the documenation for CALL SYMPUT helps explain what you're seeing:

 

"Problem: Trying to Reference a SYMPUT-Assigned Value Before It Is Available
One of the most common problems in using SYMPUT is trying to reference a macro variable value assigned by SYMPUT before that variable is created. The failure generally occurs because the statement referencing the macro variable compiles before execution of the CALL SYMPUT statement that assigns the variable's value. The most important fact to remember in using SYMPUT is that it assigns the value of the macro variable during program execution. Macro variable references resolve during the compilation of a step, a global statement used outside a step, or an SCL program. As a result:
You cannot use a macro variable reference to retrieve the value of a macro variable in the same program (or step) in which SYMPUT creates that macro variable and assigns it a value.
You must specify a step boundary statement to force the DATA step to execute before referencing a value in a global statement following the program (for example, a TITLE statement). The boundary could be a RUN statement or another DATA or PROC statement."

 

In your example the following steps take place:

1. You set x = 1 with your %let.

2. You run your data loop to set x to the value of the incrementer (why you want to do this is not clear...). This value does not get set to the symbol table until your code has run, however, per the above documentation, so your "put" statement shows the value from the %let.

3. One the data step runs, x is now set the last value of the incrementer (5). Note, however, that since it was set with call symput and not %let, it has trailing blanks. You could fix this with call symputx.

4. When you run the next data step, the same thing is happening, except the current value of x is what you last created in the previous data _null_.

 

So from my perspective, it's doing what it's supposed to do according to how the software works. Maybe a more important question is what are you trying to do?

 

 

Trusted Advisor
Posts: 1,059

Re: Issue with assinging a macro variable in a data step

Just for amusement!

 

Tom

 

%let x = 1;

data _NULL_;

do i = 1 to 5;

call symput('x', i);

y = symget('x');

put "x now is &x. and i is " i " and y is " y;

end;

run;

 

x now is 1 and i is 1 and y is 1

x now is 1 and i is 2 and y is 2

x now is 1 and i is 3 and y is 3

x now is 1 and i is 4 and y is 4

x now is 1 and i is 5 and y is 5

 

 

 

☑ This topic is SOLVED.

Need further help from the community? Please ask a new question.

Discussion stats
  • 4 replies
  • 251 views
  • 0 likes
  • 5 in conversation