SAS Combinatorial Functions: Snippets

This post was kindly contributed by From a Logical Point of View » SAS - go there to comment and to read the full post.

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(r) * 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 heck 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.

This post was kindly contributed by From a Logical Point of View » SAS - go there to comment and to read the full post.