DATA Step, Macro, Functions and more

permutations

Accepted Solution Solved
Reply
Contributor
Posts: 60
Accepted Solution

permutations

I need to create a code that will give me the below , but in a generic way

here i have 3, 2 and 1  open slots that can be filled only with A or B. but this can change in the future to 4 slots and a,b,c,d,e as a filling options. so the code need to be generic.

Any  memory efficient idea on how to tackle this?

a a b

a b a

b a a

b b a

b a b

a b b

a b

b a

a

b


Accepted Solutions
Solution
‎12-16-2011 10:58 AM
Super User
Posts: 9,681

permutations

Why my code be changed? Is there some html sensitive word in my code?

%let num_slot=3;
%let list=a,b;




%let l=%sysfunc(tranwrd("&list",%str(,),%str(",")));
options nomprint nomlogic nosymbolgen;
%macro gen;
data _null_;
%do num=&num_slot %to 2 %by -1;
%do i=1 %to &num ;
 do i&i=&l;
%end;
 if count(catx(' ',of i1 - i&num),i1) ne &num then put i1 - i&num ;
%do j=1 %to &num ;
 end;
%end;
%end;
do x=&l;put x;end;
stop;
run;
%mend gen;

%gen

Ksharp

View solution in original post


All Replies
PROC Star
Posts: 7,363

permutations

Contributor
Posts: 60

permutations

Thanks, I saw it before but this is without returns, so chip can't appear twice..

                 permutations of 4 items taken 2 at a time

                           OBS    R1         R2

                           1    Chip       Pete

                           2    Chip       Mike

                           3    Chip       William

                           4    Pete       Chip

                           5    Pete       Mike

                           6    Pete       William

                           7    Mike       Chip

                           8    Mike       Pete

                           9    Mike       William

                          10    William    Chip

                          11    William    Pete

                          12    William    Mike

PROC Star
Posts: 7,363

permutations

Why not?  You would just have to roll the permutations macro into a driver macro that accomplishes each level.  I'm not sure how you want the final file, but that could easily be accomplished with proc append.

Try, e.g.,

%macro permute(r) / parmbuff;      /* the parmbuff option assigns */

%let i=2;               /* the invocation parameter list to the */

%let things=;                       /* macro variable &syspbuff */

%do %while (%Qscan(&syspbuff,&i,%STR(,%))) ne );  /* scan the syspbuff */

    %let p&i="%Qscan(&syspbuff,&i,%STR(,%)))";  /* to determine r */

   %if &i=2 %then %let things=&&p&i;     /* and count the number */

   %else %let things=&things,&&p&i;            /* of elements, n */

   %let i=%eval(&i+1);

%end;

%let n=%eval(&i-2);

data permute&r;

    drop i j copy;

    array check (*) $ 10 r1-r&r;          /* create a total of r */

     %do m=1 %to &r;                   /* variables  for looping */

       do r&m = &things;

     %end;

     copy=0;

       do i=2 to &r;                 /* look for duplicate items */

         do j=1 to i-1;              /* and keep the unique ones */

           if check(j)=check(i) then copy+1;

         end;

       end;

     if copy = 0 then output;        /* writes to a SAS data set */

     if copy = 0 then put r1-r&r;        /* writes to the log    */

     %do m=1 %to &r;

       end;                               /* end the r DO LOOPS */

     %end;

   run;

%mend permute;

%macro allperms(k);

  %do L=1 %to &k.;

    %permute(&L.,a,b,c)

  %end;

%mend allperms;

%allperms(3)

Contributor
Posts: 60

permutations

Thanks but what i reaaly need is returns

the code give this

r1r2r3
abc
acb
bac
bca
cab
cba

but what i do not understand is how to do this on top of the above

a a a

a a b

a b b

a c c...etc

PROC Star
Posts: 7,363

permutations

If the following does what you want, then it would be easy to expand it to automatically account for the duplicates:

%permute(1,a,b,c)

%permute(2,a,a,b,b,c,c)

%permute(3,a,a,a,b,b,b,c,c,c)

Super User
Posts: 9,681

permutations

I don't understand why not like be:

aaa

bbb

a a b

a b a

b a a

b b a

b a b

a b b

a b

b a

aa

bb

a

b

%let num_slot=3;
%let list=a,b;




%let l=%sysfunc(tranwrd("&list",%str(,),%str(",")));
options nomprint nomlogic nosymbolgen;
%macro gen;
data _null_;
%do num=&num_slot %to 2 %by -1;
%do i=1 %to #
 do i&i=&l;
%end;
 if count(catx(' ',of i1 - i&num),i1) ne &num then put i1 - i#
%do j=1 %to #
 end;
%end;
%end;
do x=&l;put x;end;
stop;
run;
%mend gen;

%gen



Ksharp

Contributor
Posts: 60

permutations

Thanks Ksharp but  I get this error when running the code, I think it's related to this "#" I am not sure I fully understand how the code works, so I don't know to which number should I input there

Solution
‎12-16-2011 10:58 AM
Super User
Posts: 9,681

permutations

Why my code be changed? Is there some html sensitive word in my code?

%let num_slot=3;
%let list=a,b;




%let l=%sysfunc(tranwrd("&list",%str(,),%str(",")));
options nomprint nomlogic nosymbolgen;
%macro gen;
data _null_;
%do num=&num_slot %to 2 %by -1;
%do i=1 %to &num ;
 do i&i=&l;
%end;
 if count(catx(' ',of i1 - i&num),i1) ne &num then put i1 - i&num ;
%do j=1 %to &num ;
 end;
%end;
%end;
do x=&l;put x;end;
stop;
run;
%mend gen;

%gen

Ksharp

Contributor
Posts: 60

permutations

Thanks so much!

PROC Star
Posts: 7,363

permutations

KSharp,

While the OP appears to be satisfied with the code, I don't think it does exactly what the OP had asked for.  It appears to leave off the two and three-way same combinations like:

aaa

aa

bbb

bb

ccc

cc

Contributor
Posts: 60

permutations

you are right, I didn't catch it.

Super User
Posts: 9,681

permutations

Art.

Yes. That was what I am confused.

Actually I do not exactly know what OP want.

It is midnight at my time zone.

Good Night! Doctor Art.

Ksharp

PROC Star
Posts: 7,363

permutations

Have a good night's rest KSharp.  I was surprised to see you here this late.

Contributor
Posts: 60

permutations

ksharp, Art thank you both

I will use proc plan

☑ This topic is SOLVED.

Need further help from the community? Please ask a new question.

Discussion stats
  • 14 replies
  • 262 views
  • 6 likes
  • 3 in conversation