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

Hi,

the situation I have is a list of macro variables like follows;

var_2030

var_2031

var_2032

etc.

 

During the data step, which involves a loop, I need to use more than one:

 

data test;

x=2;

do i=1 to 3;

%let t=2030+i;

If x<&&var_&t then put 'success';

%end;

run;

 

Unfortunately, &&var_&t resolves as (var_2030) + i instead of (var_(2030+i)).

 

I've tried using %let t=%sysevalf(2030+i) but it then complains that there is a character variable instead of numeric. I also understand this may be related to macro values being evaluated before data steps are executed, so is this possible?

 

Thanks very much.

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
Reeza
Super User

@Brian3 wrote:

Hmm I've never used arrays before. Ok so

 

data test;

x=2;

%let var1=4;

%let var2=1;

%let var3=2;

array &var[3];

do i=1 to 2;

If x>&var[i] then put 'success';

end;

run;


 

The X-Y Problem, as it is sometimes called, is a mental block which leads to enormous amounts of wasted time and energy, both on the part of people asking for help, and on the part of those providing help. It often goes something like this:

  • User wants to do X.
  • User doesn't know how to do X, but thinks they can fumble their way to a solution if they can just manage to do Y.
  • User doesn't know how to do Y either.
  • User asks for help with Y.
  • Others try to help user with Y, but are confused because Y seems like a strange problem to want to solve.
  • After much interaction and wasted time, it finally becomes clear that the user really wants help with X, and that Y wasn't even a suitable solution for X.

The problem occurs when people get their train of thought stuck on one approach and become unable to take a step back. Remaining open to having a new look at the bigger picture, these people might find their way back to X and continue searching for alternative solutions.

 

https://mywiki.wooledge.org/XyProblem

 

 

 

View solution in original post

24 REPLIES 24
Reeza
Super User

From what you've posted here you should be using an array not a macro.

That being macro variables are not resolved in the same step they're created. THere are many ways to get around this, but given that you don't need macros my first suggestion is to switch to arrays instead.

 

Here's a tutorial on using Arrays in SAS
https://stats.idre.ucla.edu/sas/seminars/sas-arrays/

 


@Brian3 wrote:

Hi,

the situation I have is a list of macro variables like follows;

var_2030

var_2031

var_2032

etc.

 

During the data step, which involves a loop, I need to use more than one:

 

data test;

x=2;

do i=1 to 3;

%let t=2030+i;

If x<&&var_&t then put 'success';

%end;

run;

 

Unfortunately, &&var_&t resolves as (var_2030) + i instead of (var_(2030+i)).

 

I've tried using %let t=%sysevalf(2030+i) but it then complains that there is a character variable instead of numeric. I also understand this may be related to macro values being evaluated before data steps are executed, so is this possible?

 

Thanks very much.

 

 


 

Brian3
Obsidian | Level 7
Thanks, for the task I'm doing I have to leave them as macro variables. Is there a way to do that?
Kurt_Bremser
Super User

@Brian3 wrote:
Thanks, for the task I'm doing I have to leave them as macro variables. Is there a way to do that?

No. Macro variables are resolved during data step compilation, so there's no way you can dynamically address them depending on values present while the data step executes. This is a very typical beginner's misconception when they do not yet understand the nature of the macro language as a code generator, not a data processing tool.

 

Please give us data and the expected result.

Reeza
Super User

@Brian3 wrote:
Thanks, for the task I'm doing I have to leave them as macro variables. Is there a way to do that?

Then you need to provide a more representative sample of your issue. 

Kurt_Bremser
Super User

Your code can't run anyway because of syntax errors. You have a do without an end, and a % end without a %do.

And if it was just a typo and it is a %do, that is not possible in open code, and I see no macro definition around your code.

 

From what I can guess, I take it that you have a bad dataset design (wide instead of long/tall), forcing you to write complicated code for something that is most probably an extremely simple task in SAS, needing no macro code at all.

So you first need to make your data intelligent (Maxim 33) by transposing; for further help, please provide example data in usable form (data step with datalines), and what you want to get as a result out of it.

Brian3
Obsidian | Level 7

There should not be a %. It should be end.

Brian3
Obsidian | Level 7

it is more the principle I am trying to do rather than specific data. Basically how to work with macro variables which can change value during a data step. Surely SAS has some ability to let me do that. Maybe I can use arrays, but not sure how it works with macro variables.

 

 

Reeza
Super User
What makes you think you need macro variables at all.
Brian3
Obsidian | Level 7

its just because they are already macro variables. If there's a quick way to convert them to data values, that would be ok.

Reeza
Super User
Use the macro variables to define your array definition then, which is dynamic and then you can use the array without any issues. First develop working code - non macro. If you show us what that looks like we can help you convert it to a macro. Right now we have an xy problem.
Brian3
Obsidian | Level 7

Hmm I've never used arrays before. Ok so

 

data test;

x=2;

%let var1=4;

%let var2=1;

%let var3=2;

array &var[3];

do i=1 to 2;

If x>&var[i] then put 'success';

end;

run;

Tom
Super User Tom
Super User

No need for an array there as you are just dealing with numeric constants and not variables.

%let var1=4;
%let var2=1;
%let var3=2;

data test;
  x=2;
  if x > min(&var1, &var2, &var3) then put 'success';
run;

Much easier if you just put the list of values into a single macro variable instead.

%let list=4, 1, 2;

data test;
  x=2;
  if x > min(&list) then put 'success';
run;

Note: Make sure to move your %LET statements BEFORE the DATA statement. That is when they will execute so placing them there in the code will be less confusing to you.

Kurt_Bremser
Super User

If you want to create an array out of macro variables, see this:

%let var1=4;
%let var2=1;
%let var3=2;

data test;
x = 2;
array var[3] (&var1, &var2, &var3);
do i = 1 to 3;
  If x > var[i] then put i ', success';
end;
run;

 

  • the %let statements are now where they belong to reflect the point in time where they are resolved
  • the macro variables are used at a static point resolved during data step compilation
  • the array is defined correctly (without the erroneous macro variable reference)

 

Reeza
Super User

@Brian3 wrote:

Hmm I've never used arrays before. Ok so

 

data test;

x=2;

%let var1=4;

%let var2=1;

%let var3=2;

array &var[3];

do i=1 to 2;

If x>&var[i] then put 'success';

end;

run;


 

The X-Y Problem, as it is sometimes called, is a mental block which leads to enormous amounts of wasted time and energy, both on the part of people asking for help, and on the part of those providing help. It often goes something like this:

  • User wants to do X.
  • User doesn't know how to do X, but thinks they can fumble their way to a solution if they can just manage to do Y.
  • User doesn't know how to do Y either.
  • User asks for help with Y.
  • Others try to help user with Y, but are confused because Y seems like a strange problem to want to solve.
  • After much interaction and wasted time, it finally becomes clear that the user really wants help with X, and that Y wasn't even a suitable solution for X.

The problem occurs when people get their train of thought stuck on one approach and become unable to take a step back. Remaining open to having a new look at the bigger picture, these people might find their way back to X and continue searching for alternative solutions.

 

https://mywiki.wooledge.org/XyProblem

 

 

 

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

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
  • 24 replies
  • 1224 views
  • 12 likes
  • 4 in conversation