Hi,
On SAS EG, I want to create a macro variable looking like this :
M0_ref M1_ref M2_ref (etc)
Between each "Mn_ref" I need a space so that I can put it as an argument in a PROC TRANSPOSE step.
I want this to be automatically created, recursively (because the number of Mn_ref I need can vary).
Here is my code (&recul_max is equal to an integer) :
%macro init_string(); %global list; %let list=M0_ref; %do i=1 %to &recul_max.; %let list=%sysfunc(catx(' ',&list.,%sysfunc(cat(M,&i.,_ref)))); %end; %mend(); %init_string(); %put &=list;
Here is what I get :
LIST=M0_ref''M1_ref''M2_ref''M3_ref''
I tried a lot of different things, what do you sugget I do so it works ?
PS : I cannot add commas, also, as a separator.
Thanks in advance !
The macro processor is a text string processor, it can concatenate text strings natively, so you don't need %sysfunc(catx(...)). All you need to do is place &i in the proper location and then append to &list. So in your %DO loop, this should be all you need.
%let list=&list M&i._ref;
The macro processor is a text string processor, it can concatenate text strings natively, so you don't need %sysfunc(catx(...)). All you need to do is place &i in the proper location and then append to &list. So in your %DO loop, this should be all you need.
%let list=&list M&i._ref;
Extra bonus comment:
I want this to be automatically created, recursively (because the number of Mn_ref I need can vary).
You would make your programming much much much easier if you use Mref_1 Mref_2 etc. as your variable names instead of M1_ref M2_ref etc. Why? Because Mref_1 through Mref_27 can be abbreviated as either Mref: or Mref_1-Mref_27, both of which produce the same results but the first doesn't require that you know there are 27 of them and hard code 27 into your program. No similar abbreviations exist if your variable names are M1_ref M2_ref and then you have to resort to the much harder programming of a macro to create the desired list of variable names.
@PaigeMiller wrote:
You would make your programming much much much easier if you use Mref_1 Mref_2 etc. as your variable names instead of M1_ref M2_ref etc. Why? Because Mref_1 through Mref_27 can be abbreviated as either Mref: or Mref_1-Mref_27, both of which produce the same results but the first doesn't require that you know there are 27 of them and hard code 27 into your program. No similar abbreviations exist if your variable names are M1_ref M2_ref and then you have to resort to the much harder programming of a macro to create the desired list of variable names.
Thanks for the additional info, I chose this syntax as I have other variable named M1, M2 etc. It's just so the dataset is more clearly understandable.
Anyway, you answered my question perfectly, thank you !
chose this syntax as I have other variable named M1, M2 etc. It's just so the dataset is more clearly understandable.
That's fine, but isn't Mref_1 Mref_2 just as understandable? it certainly has the benefit of being easier to program.
You have been given good advice and I agree on the variable rename. However, there is an easier way, IMO. Here is pseudocode off the top of my head but illustrates the concept. Spin it out then bring it back in. Much, much easier to debug and gets rid of macros to boot.
filename temp 'c:\temp\MyGen.sas';
data _null_ ;
file temp;
do i=1 to 27;
put 'M' i '_' ...etc....;
end;
run;
%include temp;
See here: https://github.com/savian-net/SasTipsTricks#put-statements-vs-macros
Hello @AlanC , I'm not sure if I understand your point.
Renaming to Mref_1, Mref_2, ... gets rid of macros too, no need for the type of macro looping in the original post, no need for looping within a data step either.
Agreed on your point Paige which I mentioned. It is a generalized comment as well that allows for clear transparency as to what is happening.
It is a good idea but as I'm not the only one reading this dataset, it should remain as clear as possible.
But I also find clear advantages to renaming these variables. I guess I may do it later, but at least I've learnt how to it this way.
@AlanC I will try what you showed me. However are you sure it can provide me a macro variable as I need it ? Looking at the tests I've done quickly so far, it didn't make it happen
Thanks all
Read the code portion I linked to. Yes, it can provide the macro variables but remember that macro variables are not special. SAS macros are code generation so you can supplant the code generation using other tools. Oftentimes, I write SAS using C#. Anything that can codegen can supplant macros and is often much easier to maintain. You can see the Base SAS being generated, clearly. You can run the generated code on its own.
I built a product for SAS using the technique so it is capable of doing everything you need. Macro variables are hard to debug, maintain, transfer knowledge to new people, etc.. Clear code is much better. Take the time to understand what the code snippet is doing.
Anything you can do in a DATA step can be turned into a macro variable.
If you have created a text string in variable STRING, and you want it to become a macro variable named &STRING, in the same data step use use:
call symputx('string',string);
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 16. Read more here about why you should contribute and what is in it for you!
What’s the difference between SAS Enterprise Guide and SAS Studio? How are they similar? Just ask SAS’ Danny Modlin.
Find more tutorials on the SAS Users YouTube channel.
Select SAS Training centers are offering in-person courses. View upcoming courses for: