BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
hhchenfx
Barite | Level 11

Hi,

I have a long list of factors and I need to analyze 3 factors at a time.

The idea is that the Outer_loop will slide out 3 factors and then the Inner_Loop will do the analysis.

This code below move element 1 by 1. 

How can I take group of 3?

Thank you,

HHC

%let my_list = min0 min1 min2 min3 min4 min5;

%MACRO OUTER_LOOP;
	%do i=1 %to %sysfunc(countw(&my_list));
	%let list_of_3=%scan(&my_list,&i);
	%put &list_of_3;
/*
		%MACRO INNER_LOOP;
			%do J=1 %to %sysfunc(countw(&list_of_3));
			*MY ANALYSIS;
			%end;
		%MEND;

		%MACRO INNER_LOOP; *Run inner loop;
*/
	%end;
%mend;

%OUTER_LOOP;run;

 

1 ACCEPTED SOLUTION

Accepted Solutions
Kurt_Bremser
Super User

Use an additional delimiter:

%let my_list = min0 min1 min2|min3 min4 min5;

%MACRO OUTER_LOOP;
	%do i=1 %to %sysfunc(countw(&my_list,|));
	%let list_of_3=%scan(&my_list,&i,|);

or use a different increment:

%let my_list = min0 min1 min2 min3 min4 min5;

%MACRO OUTER_LOOP;
	%do i=1 %to %sysfunc(countw(&my_list)) %by 3;
	%let list_of_3=%scan(&my_list,&i) %scan(&my_list,%eval(&i+1)) %scan(&my_list,%eval(&i+2));

View solution in original post

6 REPLIES 6
Kurt_Bremser
Super User

Use an additional delimiter:

%let my_list = min0 min1 min2|min3 min4 min5;

%MACRO OUTER_LOOP;
	%do i=1 %to %sysfunc(countw(&my_list,|));
	%let list_of_3=%scan(&my_list,&i,|);

or use a different increment:

%let my_list = min0 min1 min2 min3 min4 min5;

%MACRO OUTER_LOOP;
	%do i=1 %to %sysfunc(countw(&my_list)) %by 3;
	%let list_of_3=%scan(&my_list,&i) %scan(&my_list,%eval(&i+1)) %scan(&my_list,%eval(&i+2));
Tom
Super User Tom
Super User

Note that %EVAL() is not need, the macro processor will already evaluate the second parameter to %SCAN() with %EVAL().

%let list_of_3=%scan(&my_list,&i) %scan(&my_list,&i+1) %scan(&my_list,&i+2);

Also it is not sure what is desired when the number of names in the list is not divisible by 3.  In those cases your logic will generate LIST_OF_3 with only one or two names instead of three the last time through the outer loop since %SCAN() returns empty string with you scan past the end of the list.

hhchenfx
Barite | Level 11

Thanks you all.

@Kurt_Bremser code work perfectly well.

HHC

SubbuPaz
SAS Employee

Try this:

 

%let my_list = min0 min1 min2 min3 min4 min5;

/* Outer loop macro */
%MACRO OUTER_LOOP;
%global list_of_3; %global j;
%local k;
%let j=1; /* Initializing a global variable j to 1 */
/* Looping till j < size of &my_list */
%do %while (&j <= %sysfunc(countw(&my_list)));
%let list_of_3=;
/* Looping to create &list_of_3 */
%do k=&j. %to (&j.+2);
%let list_of_3 = &list_of_3 %scan("&my_list", &k, " ");
%end;
%put Inital Value of j = &j.;
%put List in Outer Loop= &list_of_3.;
%INNER_LOOP; /* calling inner loop macro for analysis */
%let j=%eval(&j.+3); /* Updating j */
%put Updated Value of j = &j.;
%end;
%mend OUTER_LOOP;

/* Inner loop macro */
%MACRO INNER_LOOP;
%local l;
%put List in Inner Loop= &list_of_3.;
%do l=1 %to %sysfunc(countw(&list_of_3));
*MY ANALYSIS;
%end;
%MEND INNER_LOOP;

%OUTER_LOOP;
run;
SubbuPaz
SAS Employee

Hi, If you need all possible 3-element subsets of the list of factors like @FreelanceReinh asked in his post, you could modify the below line in my suggested code:

 

%let j=%eval(&j.+1); /* Updating j */

Thanks.

FreelanceReinh
Jade | Level 19

Hi @hhchenfx,


@hhchenfx wrote:

I have a long list of factors and I need to analyze 3 factors at a time.

Do you need all possible 3-element subsets of the list of factors? Then see if this could serve as a template for your "outer loop":

%let my_list = min0 min1 min2 min3 min4 min5;

%macro comb3(list);
%local i j k n;
%let n=%sysfunc(countw(&list));
%put All comb(&n,3)=%sysfunc(comb(&n,3)) combinations of three elements of {&list}:;
%do i=1 %to &n-2;
  %do j=&i+1 %to &n-1;
    %do k=&j+1 %to &n;
      %put %scan(&list,&i) %scan(&list,&j) %scan(&list,&k);
    %end;
  %end;
%end;
%mend comb3;

%comb3(&my_list)

Result:

All comb(6,3)=20 combinations of three elements of {min0 min1 min2 min3 min4 min5}:
min0 min1 min2
min0 min1 min3
min0 min1 min4
min0 min1 min5
min0 min2 min3
min0 min2 min4
min0 min2 min5
min0 min3 min4
min0 min3 min5
min0 min4 min5
min1 min2 min3
min1 min2 min4
min1 min2 min5
min1 min3 min4
min1 min3 min5
min1 min4 min5
min2 min3 min4
min2 min3 min5
min2 min4 min5
min3 min4 min5

 

SAS Innovate 2025: Call for Content

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 25. Read more here about why you should contribute and what is in it for you!

Submit your idea!

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
  • 6 replies
  • 858 views
  • 7 likes
  • 5 in conversation