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

I am trying to create new variables based on the value of a macro variable created in the same data step.  But I can't get this working. Can anyone help with this please?

 

The output I want to see is creation of new variables Month1-Month10 while reading in the first observation (&z=1).  When reading the second observation, variables Month2-Month10 are populated (&z=2).

 

data test;
	v=1; w=0.5; output;
	v=2; w=0.7; output;
run;
%symdel z;
data test2;
	set test;
	call symput('z',compress(put(v,8.)));
	%macro test;
	%do t=&z %to 10;
		month&t = 2*w;
	%end;
	%mend;
	%test;
run;
%put &z;

WARNING: Apparent symbolic reference Z not resolved.
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was:
&z
ERROR: The %FROM value of the %DO T loop is invalid.
ERROR: The macro TEST will stop executing.
1 ACCEPTED SOLUTION

Accepted Solutions
Reeza
Super User

Using a sledgehammer for a thumbtack or job security I suppose.

 

This is also asked and answered frequently.

http://communities.sas.com/t5/Base-SAS-Programming/Create-increment-and-use-a-macro-variable-in-the-...

 

http://communities.sas.com/t5/General-SAS-Programming/Resolving-variable-value-as-a-macro-variable-v...

 

 

Why you shouldn't do this:

1. Hard to read code

2. Pain to maintain code

3. Because of #1/2 requires more documentation

4. If you insist on a method that defies logic it usually means it's homework....

 

View solution in original post

16 REPLIES 16
LinusH
Tourmaline | Level 20

1. It's very confusing to read code where a macro is defined within a data step.

2. Why use a macro at all in this case? Pretty sure you can accomplish this task with standard datastep code.

3. Why do you want to read the value of the macro variable within the same data step? I can't imagine any case where that is necessary. Just use the value of variable v directly.

 

Data never sleeps
gaussian
Fluorite | Level 6

The data is much more complex than shown here.  I am trying to perform some operations on about 30 variables and which variables will be processed in a given record is dicated by information contained in a separate indicator variable. The macro is supposed to automate this logic. 

ballardw
Super User

@gaussian wrote:

 I am trying to perform some operations on about 30 variables and which variables will be processed in a given record is dicated by information contained in a separate indicator variable. . 


This looks like a use of SELECT block:

Select (indicatorvariable);

   when (1) do; <block of statements to execute when the indicator variable is 1>

                  end;

   when (2) do; <block of statements to execute when the indicator variable is 2>

                  end;

   when (3) do; <block of statements to execute when the indicator variable is 3>

                  end;

   otherwise do; <whatever when indicator has any value except 1, 2 or 3>

                   end;

end;

If the indicator is text then the values in the when go in quotes: when ('ABCD')

Only one of the blocks of code will be done.

If you have multiple values of the indicator that do the same thing then use: when (1,2,3)

Kurt_Bremser
Super User

@gaussian wrote:

The data is much more complex than shown here.  I am trying to perform some operations on about 30 variables and which variables will be processed in a given record is dicated by information contained in a separate indicator variable. The macro is supposed to automate this logic. 



The variable that controls which statements need to be executed is part of your data step PDV, so you can use it with data step language tools.

NO macro processing needed.

Astounding
PROC Star

I agree ... this is in no way supposed to be a macro application.  There's nothing wrong with a DATA step saying:

 

do t=z to 10;

 

And there's nothing wrong with an array containing MONTH1-MONTH10 within a DATA step and coding:

 

m{t} = w * 2;

 

There is no such thing as a DATA step that changes its statements for each observation.  The DATA step code must end up being a constant set of characters, whether macro language is involved or not.

 

Good luck.

gaussian
Fluorite | Level 6
Arrays will work but I prefer macro programming.
Reeza
Super User

Using a sledgehammer for a thumbtack or job security I suppose.

 

This is also asked and answered frequently.

http://communities.sas.com/t5/Base-SAS-Programming/Create-increment-and-use-a-macro-variable-in-the-...

 

http://communities.sas.com/t5/General-SAS-Programming/Resolving-variable-value-as-a-macro-variable-v...

 

 

Why you shouldn't do this:

1. Hard to read code

2. Pain to maintain code

3. Because of #1/2 requires more documentation

4. If you insist on a method that defies logic it usually means it's homework....

 

Astounding
PROC Star

Well, there's just one macro tool that will do what you ask.  I don't think I'm helping you by telling you this, since all it will do is complicate the program unnecessarily (and you will still end up using arrays anyway).

 

CALL SYMPUT is a DATA step tool that transfers information from the DATA step to a macro variable.

 

SYMGET is a DATA step tool that transfers in the opposite direction, from a macro variable to a DATA step variable.

 

You can use both in the same DATA step, to transfer information to a macro variable and get it back again later.

 

All that being said, it's the wrong tool for the job.  But at least you will get some practice using these tools.

Kurt_Bremser
Super User

@gaussian wrote:
Arrays will work but I prefer macro programming.

This is NOT a matter of preference. Macro language is simply NOT the right tool for this.

Use a hammer for nails, a screwdriver for screws, and a spanner for nuts.

LinusH
Tourmaline | Level 20

Let me once again state that having lots of variable will itself complicate things, and lead people out on various hard coded solutions (or in this situation, misuse of macro).

 

Transpose your data to long.

 

So your indicator is "v", and then you have "w" that should be used in data transformation.

This should work just fine with a transposed, normalised table.

 

Storing values as columns is awkward. Leave all your Excel thinking behind.

Data never sleeps
Kurt_Bremser
Super User

CALL SYMPUT is a data step subroutine that will execute during data step execution time.

%macro starts a macro definition and will be handled as soon as the % character is encountered when the code is initially read by the main SAS interpreter; this happens before the data step is even compiled, and therefore also long before the data step starts executing.

 

Others have already stated that array processing is the way to go with your example; heed their advice. They know what they're talking about.

RW9
Diamond | Level 26 RW9
Diamond | Level 26

I would quite agree with @LinusH and @Kurt_Bremser here.  It is a fundemental lack of understanding as to what Macro language is and for.  Base SAS is the programming language, this is the one that gets compiled, manipulates and processes data.  Macro language does nothing other than generate some text which could be valid Base SAS syntax.  I repeat, it is not in any way a programming language in and of itself, only a method of simplfying the amount of text you type.  Hence, any program should be written specifically for Base SAS, unless there are very good reason why not.  In 99% of these cases where macro is used, it is one of two things - a lack of knowledge of the Base SAS system, or a lack of understanding of the data being used/ability to change its strcuture.  

 

If you post some test data, in the form of a dataset, and what you want the output to look like, we can provide Base SAS code, which is both easy to read, maintain, and not obfuscated by macro calls, and assignments.

gaussian
Fluorite | Level 6

I beg to disagree.  Macro coding is very common in financial and economic time-series models and data operations.  I had worked for several years at a top economic consulting firm and they used extensively macro coding to extend economic variables several months and years into the future.  Their legacy SAS code they have dates back to 1-3 decades -- so don't say they don't know what they are doing. Macros are more useful and readable than arrays especially when you have several dozens of time-series indicators you are working with at the same time.

 

I have solved my problem using arrays for the time being.

 

 

Reeza
Super User

@gaussian wrote:

Their legacy SAS code they have dates back to 1-3 decades -- so don't say they don't know what they are doing. 

 

I have solved my problem using arrays for the time being.

 

 


 

Given the situation you presented, arrays are optimal.

What was an optimal solution 1 to 3 decades ago, is not the same solution today given the advances in technology.

 

If your question is answered, please mark it as such.

 

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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
  • 16 replies
  • 3846 views
  • 20 likes
  • 7 in conversation