Generate All Unique Permutations of an Array in SAS

不羁岁月 提交于 2021-02-07 14:36:32

问题


In SAS if I have a string or an Array like the following,

array x[4] $1 ('A' 'B' 'C' 'D');

I need to generate all "Unique" permutations of the elements like the following,

[ABCD]
[ABC]
[BCD]
[ACD]
[ABD]
[AB]
[AC]
[AD]
[BC]
[BD]
[CD]
[A]
[B]
[C]
[D]

Is there a function in SAS for generating all possible combinations of the array?


回答1:


Assumption: I believe you are looking for combinations and not permutations, so the order does not matter, BA and AB are same thing.

Use call allcomb subroutine and comb function to find out the possible combinations.

Read more about allcomb and comb here

  • http://support.sas.com/documentation/cdl/en/lefunctionsref/63354/HTML/default/viewer.htm#p0yx35py6pk47nn1vyrczffzrw25.htm

and here

  • http://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a001009658.htm

In short -

  • call allcomb subroutine gives the possible combinations out of n elements when r of them are taken and
  • comb function gives you how many combinations it would be when out of n elements r of them are taken at a time.

data test(keep=my_string);
length my_string $50.;
  array a[4] $ ('A' 'B' 'C' 'D');

  n = dim(a);

   do k=1 to n;
         do j=1 to comb(n,k);
             call allcomb(j,k,of a[*]);
                 do i = 1 to k;
                    if i=1 then do; my_string="";counter=0;end;
                    counter=counter+1;
                    my_string=cat(compress(my_string),compress(a[i]));
                 if counter=k then output;

                 end;
           end;
    end;
run;



回答2:


A slightly different take on this is to use proc summary.

Create a dummy dataset. Assign each element of the array to a variable so we can feed it into proc summary:

data tmp;
  array arr[*] a b c d (1 1 1 1);
run;

Run proc summary.

proc summary data=tmp noprint missing;
  class a b c d;
  output out=combinations;
run;

You can also use the ways or types statements in proc summary to limit any combinations you may want.

Now the interesting side effect of doing this is that you get the _type_ column in the output dataset as well. In the example above the following values would be assigned:

D = 1
C = 2
B = 4
A = 8

So if the _type_ value in the output dataset is 13, then we know that the row was generated by combining A, B and D (8 + 4 + 1).




回答3:


Here is a quick script that will find the combinations of the individual characters within a string. This could be easily adapted to work with arrays if you prefer. Rather than using the combinational functions and call routines (all*, lex*, ran*) this approach creates the permutations by using the binary representation of integers up to 2**len. I prefer this approach as I think it demonstrates what is happening, is more transparent and doesn't change the order of the array assignments.

data have;
    str = "123456"; output;
    str = "ABCD"; output;
run;
data want;
    set have;
    length comb $20.;
    len = length(str);
    /* Loop through all possible permutations */
    do _i = 0 to 2**len - 1;
        /* Store the current iteration number in binary */
        _bin = putn(_i, "binary" || put(len, best.) || ".");
        /* Initialise an empty output variable */
        comb = "";
        /* Loop through each value in the input string */
        do _k = 1 to len;
            /* Check if the kth digit of the binary representation is 1 */
            /* And if so add the kth input character to the output */
            if substr(_bin, _k, 1) = "1" then 
                comb = cats(comb,  substr(str, _k, 1));
        end;
        output;
    end;
    /* Clean up temporary variables, commented so you can see what's happening */
/*  drop _:; */
run;

If you do want permutations then a similar approach is possible using factoradic representations of the numbers. But, I would recommend that you use a combinational function instead as the conversions would be much more involved. It's probably quite a nice coding exercise for learning though.


It would be great if SAS had a function for reducing strings by boolean patterns, but it probably wouldn't get much use.

bsubstr("ABCD", "1010") --> "AC"
bsubstr("ABCD", "1110") --> "ABC"
bsubstr("ABCD", "0001") --> "D"



回答4:


SAS has in-built functions to calculate combinations & permutations, allcomb and allperm.

SAS Documentation for ALLCOMB function : http://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a003112305.htm



来源:https://stackoverflow.com/questions/29340151/generate-all-unique-permutations-of-an-array-in-sas

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!