在SAS中生成阵列的所有唯一排列

时间:2015-03-30 07:01:52

标签: arrays sas

在SAS中,如果我有一个字符串或数组如下,

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

我需要生成元素的所有“唯一”排列,如下所示

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

SAS中是否有用于生成阵列所有可能组合的功能?

4 个答案:

答案 0 :(得分:3)

假设:我认为您正在寻找combinations而不是permutations,因此订单无关紧要,BAAB是同样的事情。

使用call allcomb子例程和comb函数找出可能的组合。

详细了解allcombcomb

在这里

简而言之 -

  • call allcomb子例程在n元素被采用时提供了r个元素的可能组合
  • comb函数可以为您提供一次nr个元素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; 时的组合数。

{{1}}

答案 1 :(得分:3)

稍微不同的是使用proc summary

创建虚拟数据集。将数组的每个元素分配给变量,以便我们可以将其提供给proc summary

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

运行proc summary

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

您还可以使用ways中的typesproc summary语句限制您可能需要的任何组合。

现在,这样做的有趣副作用是您也可以在输出数据集中获得_type_列。在上面的示例中,将分配以下值:

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

因此,如果输出数据集中的_type_值为13,那么我们就知道该行是通过组合A,B和D(8 + 4 + 1)生成的。

答案 2 :(得分:2)

这是一个快速脚本,可以找到字符串中各个字符的组合。如果您愿意,这可以很容易地适应阵列。这种方法不是使用组合函数和调用例程(all*lex*ran*),而是使用最大为2**len的整数的二进制表示来创建排列。我更喜欢这种方法,因为我认为它演示了正在发生的事情,更透明,并且不会改变数组赋值的顺序。

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;

如果你想要排列,那么可以使用数字的实际表示来similar approach。但是,我建议您使用组合函数,因为转换将涉及更多。尽管如此,这可能是一个很好的编码练习。


如果SAS具有通过布尔模式减少字符串的功能,那将会很棒,但它可能没有多大用处。

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

答案 3 :(得分:0)

SAS具有内置功能来计算组合和功能。排列,allcomballperm

ALLCOMB功能的SAS文档:http://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a003112305.htm