在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中是否有用于生成阵列所有可能组合的功能?
答案 0 :(得分:3)
假设:我认为您正在寻找combinations
而不是permutations
,因此订单无关紧要,BA
和AB
是同样的事情。
使用call allcomb
子例程和comb
函数找出可能的组合。
详细了解allcomb
和comb
在这里
简而言之 -
call allcomb
子例程在n
元素被采用时提供了r
个元素的可能组合comb
函数可以为您提供一次n
个r
个元素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
中的types
或proc 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具有内置功能来计算组合和功能。排列,allcomb
和allperm
。
ALLCOMB功能的SAS文档:http://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a003112305.htm