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

Hi, 

 

I'm trying to set up a SAS EG project where multiple macro variables are create at the beginning of the project. These variables are A, A1, A2, A3, A4 and must obey the following rules:

 

  • A is introduced by the user and must be an integer between 1 and 13
  • A1 = A-1; A2=A-2 ....
  • if any of the variables is below 1 than it should go from 13 backwords

 

I define A using a prompt and All the rules are defined so my problem is with the other variables that depende on A. 

In python I would just use a list and define the variables using negative indexes. Is any way to do this in SAS other than programming a condition for each variable?

 

Thanks in advance

 

1 ACCEPTED SOLUTION

Accepted Solutions
Ricardo_Neves
Obsidian | Level 7

Thanks @WarrenKuhfeld I used your code and modified it a bit to fit my purpose.

 

Here is the final version

%let Alist =1 2 3 4 5 7 8 9 10 11 12 13;
%let A = 1;

data _null_ (drop=i);
array A(4);
do i=1 to 4;
A{i} = scan("&Alist.",ifn(&A-i le 0,&A-i-1,&A-i));
call symputx(cats('A',i),A(i));
end;
run;

%put _user_;

View solution in original post

8 REPLIES 8
BrunoMueller
SAS Super FREQ

Please tell us more on what is the purpose of creating these macro variables, what are they used for.

 

To process something within a loop you need to create a macro program, the code below shows an example that creates as many macro variables as you need with the proper content.

 

Note, that once you have a global macro variable, it is there to stayin your SAS session, unless you delete them using %SYMDEL.

 

%let a = 10;

%macro createVars;
  %local i;
  %do i = 1 %to &a;
    %global a&i;
    %let a&i = &i;
  %end;
%mend;

%createVars

%put _user_;
Ricardo_Neves
Obsidian | Level 7
Hi, This project will run in cycles (13 each year), and in some processes I have to check the results of previous cycles (sometimes up to 4 cycles back). For that I defined these variables so that every time I run the project it will automatically find the tables marked as the previous cycle (for example we are now on cylce 13 so I need to check some info from cycle 12, 11, 10...).
Since will be starting a new year, this will reset, so in January will start cycle 1 of 2018, but I still need to check cycles 13, 12, 11 and 10 of 2017, and when a cycle 2 starts I need cycle 1 of 2018, 1, 13, 12 ,11.

What I want is for the variables A1, A2 A3 to update automatically when I define A.
RW9
Diamond | Level 26 RW9
Diamond | Level 26

Macro is really not the best methodolgy.  Macro is nothing more than a text find/replace system.  Its not good to try to use it for data processing.  

What purpose is there in a having X amount of text macro variables which essentially hold something as simple as the formula?

Have your prompt supply A.  Then whenever you want to use it, the formula is simply &A. - x where x is the iterator in question.  There seems no logical reason to keep each evaluated version.

WarrenKuhfeld
Rhodochrosite | Level 12

Something like this?

%let a = 2;
data _null_;
a = &a;
do i = 1 to 13;
   a = ifn(a - 1 le 0, 13, a - 1);
   call symputx(cats('a', i), a);
   end;
run;
%put _user_;
Ricardo_Neves
Obsidian | Level 7

Thanks @WarrenKuhfeld I used your code and modified it a bit to fit my purpose.

 

Here is the final version

%let Alist =1 2 3 4 5 7 8 9 10 11 12 13;
%let A = 1;

data _null_ (drop=i);
array A(4);
do i=1 to 4;
A{i} = scan("&Alist.",ifn(&A-i le 0,&A-i-1,&A-i));
call symputx(cats('A',i),A(i));
end;
run;

%put _user_;
WarrenKuhfeld
Rhodochrosite | Level 12

OK. Glad I could help.  I am not sure why you are using arrays.  You certainly don't need to ever drop a variable with DATA _NULL_.  The whole point of DATA _NULL_ is you are not making a data set.

Ricardo_Neves
Obsidian | Level 7
Yes you're right ,for this particular case it is not necessary, but I will have to do other calculations inside the loop using the obtained value. That is why I'm using them
Tom
Super User Tom
Super User

You could easily generate the macro variables using a data step.

data _null_;
 do i=1 to 13 ;
   result=&a-i+13*(&a<=i);
   put i= result= ;
   call symputx(cats('a',i),result);
 end;
run;

But how are you using these 13 extra macro variables?  Perhaps it would just be easier to create a macro to emit the relative number you need instead of making a bunch of macro variables.

%macro relative(x);
%eval(&a-&x+13*(&a<=&x))
%mend relative ;

Then instead of referencing &A4 you could reference %RELATIVE(4).

 

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
  • 8 replies
  • 3490 views
  • 3 likes
  • 5 in conversation