3 min read

SAS Combinatorial Functions: Snippets

1. Permutation and Combination

data null;
n = 5;
r = 2;

   *the factorial of a number;
fact=fact(n);

   *for positive integers, fact(n) = gamma(n+1);
gamm=gamma(n + 1);

   *C(n,r): number of combinations of n objects selected r ;
*n! / [r!(n-r)!];
comb1 = comb(n,r);
comb2 = fact(n) / (fact® * fact(n-r));
comb3 = gamma(n+1) / (gamma(r+1) * gamma(n-r+1));
comb4 = exp(lcomb(n,r));
comb5 = exp(lgamma(n+1)-lgamma(r+1)-lgamma(n-r+1));

   *A(n,r): number of permutation (ordered arrangements);
*n! / (n-r)!;
perm1 = perm(n,r);
perm2 = fact(n) /  fact(n-r);
perm3 = gamma(n+1) /  gamma(n-r+1);
perm4 = exp(lperm(n,r));
perm5 = exp(lgamma(n+1)-lgamma(n-r+1));

   put (all) (= / );
run;

Note functions fact() and gamm() can quickly reach out their limitations(try n=171 and check the overflow notes in Log window).

2. Generate Unique Pairs

Question see here.

data null;
array x[5] $1 (“A” “C” “D” “B” “E”);
n = dim(x);
r = 2;
ncomb = comb(n, r);
do j = 1 to ncomb+1;
rc = allcomb(j, r, of x[*]);
if rc < 0 then leave;
put j 5. +3 x1 “- ” x2 +3;
end;
run;

The output in Log:

1   A – C
2   A – E
3   A – B
4   A – D
5   C – D
6   C – E
7   C – B
8   D – B
9   D – E
10   B – E

Or if you like alphabetical sorted pairs:

data null;
array x[5] $1 (“A” “C” “D” “B” “E”);
n = dim(x);
r = 2;
ncomb = comb(n, r);
do j = 1 to ncomb+1;
rc = lexcomb(j, r, of x[*]);
if rc < 0 then leave;
put j 5. +3 x1 “- ” x2 +3;
end;
run;

The output:

1   A – B
2   A – C
3   A – D
4   A – E
5   B – C
6   B – D
7   B – E
8   C – D
9   C – E
10   D – E

I checked Rick Wicklin’s blog and found  PROC IML offers a much more intuitive approach to this problem:

proc iml;
n = 5;
r = 2;
idx = allcomb(n, r);
print idx;
quit;

The output:

1 2
2 3
1 3
3 4
2 4
1 4
4 5
3 5
2 5
1 5

or make the output more readable:

proc iml;
n = 5;
r = 2;
idx = allcomb(n, r);
print idx;

    Items = {“A” “C” “D” “B” “E”};
S = Items[ ,idx];
S = shape(S, 0, r);
print S[r=(char(1:nrow(S)))];
quit;

the output:

1  A C
2  C D
3  A D
4  D B
5  C B
6  A B
7  B E
8  D E
9  C E
10 A E

3. Generate Unique Pairs: A Macro

Years ago when the build-in functions above might not be available in SAS, a macro %combo did the same job:

%combo(2,a,c,d,b,e)

The output:

1  a c
2  a d
3  a b
4  a e
5  c d
6  c b
7  c e
8  d b
9  d e
10 b e

It’s fun to check out the macro how to implement it by arrays.