问题
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 allcombsubroutine gives the possible combinations out ofnelements whenrof them are taken andcombfunction gives you how many combinations it would be when out ofnelementsrof 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