Barite | Level 11

Slide a list into smaller list

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
Super User

Re: Slide a list into smaller list

``````%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));``````
6 REPLIES 6
Super User

Re: Slide a list into smaller list

``````%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));``````
Super User

Re: Slide a list into smaller list

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.

Barite | Level 11

Re: Slide a list into smaller list

Thanks you all.

@Kurt_Bremser code work perfectly well.

HHC

SAS Employee

Re: Slide a list into smaller list

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;`
SAS Employee

Re: Slide a list into smaller list

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.

Re: Slide a list into smaller list

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```

Discussion stats
• 6 replies
• 607 views
• 7 likes
• 5 in conversation