BookmarkSubscribeRSS Feed
braam
Quartz | Level 8

I have a macro variable, ID_LIST, that has a value of "1 2 3 4 6 8". This macro is generated from a dataset (using PROC SQL SELECT). I would like to parse them into each number, and generate another macro variable that is "contrast id1 1, id2 1, id3 1, id4 1, id6 1, id8 1" so that I can use this to perform wald test when I use PROC SURVEYREG. Thanks in advance.

 

What I have: a macro variable having "1 2 3 4 6 8"

What I would like to have: a macro variable having "contrast id1 1, id2 1, id3 1, id4 1, id6 1, id8 1"

 

8 REPLIES 8
mkeintz
PROC Star

@braam wrote:

….
This macro is generated from a dataset (using PROC SQL SELECT).

...

What I have: a macro variable having "1 2 3 4 6 8"

What I would like to have: a macro variable having "contrast id1 1, id2 1, id3 1, id4 1, id6 1, id8 1"


You can use a minor variation of your SELECT clause to generate the comma-separated contrast specification, as in:

 

proc sql noprint;
  select distinct cats('ID',age)||' 1' into :contrast_list separated by ','
  from sashelp.class;
quit;
%put &=contrast_list;

Then, later in your analysis code, you can have the statement:

contrast &contrast_list ; 

 

--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------
braam
Quartz | Level 8

Thanks! Can I do something like this to keep two lists, one for the original list and the other for the list for contrast statement later? The below code doesn't work.

 


proc sql noprint;
	select distinct age into :age_list separated by ',',
	select distinct cats('ID',age)||' 1' into :contrast_list separated by ','
	from sashelp.class;
quit;
Quentin
Super User

Yes, you can generate two lists using one SELECT statement.  You list the columns for the select statement, and list the macro variables on the INTO clause, e.g. :

 

1    proc sql noprint;
2      select distinct
3            age
4          , cat('ID',age,' 1')
5       into :age_list separated by ','
6          , :contrast_list separated by ','
7      from sashelp.class;
8    quit;

9
10
11   %put >>&age_list<< >>&contrast_list<< ;
>>11,12,13,14,15,16<< >>ID11 1,ID12 1,ID13 1,ID14 1,ID15 1,ID16 1<<
The Boston Area SAS Users Group is hosting free webinars!
Next webinar will be in January 2025. Until then, check out our archives: https://www.basug.org/videos. And be sure to subscribe to our our email list.
hashman
Ammonite | Level 13

@braam:

I'd follow @mkeintz's sage advice and create your required macro variable the way you need from the outset. But if you have your already generated 1 through 8 and want to transform it in the string you've indicated, this will work, however unseemly it may look:

%let h = 1 2 3 4 5 6 7 8 ;                                                                                                              
                                                                                                                                        
%let w = contrast %sysfunc (tranwrd (%sysfunc (tranwrd (%str( )&h, %str( ), %str( )id)), %str( ), %str( 1, ))) 1 ;                      
                                                                                                                                        
%put &w ;     

Kind regards

Paul D.

ScottBass
Rhodochrosite | Level 12
%let id_list=1 2 3 4 6 8;
%macro code;
id&word 1^
%mend;
%put contrast %seplist(%loop(&id_list),indlm=^);

I would put "contrast" in at the proper location in SURVEYREG, rather than in your macro variable.  I would also "inject" the commas at the proper location using %seplist, rather than in your macro variable.  I never put "syntax" (esp. commas, but also quotes, etc.) in my macro variable metadata if I can help it.  Commas can be especially problematic.

 

https://github.com/scottbass/SAS/blob/master/Macro/loop.sas

https://github.com/scottbass/SAS/blob/master/Macro/seplist.sas

https://github.com/scottbass/SAS/blob/master/Macro/parmv.sas


Please post your question as a self-contained data step in the form of "have" (source) and "want" (desired results).
I won't contribute to your post if I can't cut-and-paste your syntactically correct code into SAS.
hashman
Ammonite | Level 13

@ScottBass

>I would put "contrast" in at the proper location in SURVEYREG, rather than in your macro variable.<

Agreed. But in the real world, I'd do it as @mkeintz has suggested. There's no need for any of these macro transmutations when the needed list can be composed as required from the outset.

 

Kind regards

Paul D. 

ScottBass
Rhodochrosite | Level 12

@hashman wrote:

@ScottBass

>I would put "contrast" in at the proper location in SURVEYREG, rather than in your macro variable.<

Agreed. But in the real world, I'd do it as @mkeintz has suggested. There's no need for any of these macro transmutations when the needed list can be composed as required from the outset.

 

Kind regards

Paul D. 


 

Also agree(ish).  I edited my post to indicate why.  It's my own coding style but IMO has served me well. 

 

In SAS, as in Perl, TIMTOWTDI.


Please post your question as a self-contained data step in the form of "have" (source) and "want" (desired results).
I won't contribute to your post if I can't cut-and-paste your syntactically correct code into SAS.

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 8 replies
  • 1766 views
  • 1 like
  • 6 in conversation