Hi there:
i have this 5 names:
data have;
input names$;
cards;
aaaa
bbbb
cccc
dddd
eeee;
now need to obtain the combination NOT ALEATORY, by steps like this,
i) the firt table i need to obtain is simple: is the raw data;
ii)the second table is where my problems begin because i need to combinate the names in couples and it can not be repeated like this:
want:
aaaa bbbb
aaaa cccc
aaaa dddd
aaaa eeee
bbbb cccc
bbbb dddd
bbbb eeee
cccc dddd
cccc eeee
dddd eeee
and the third table comes in triplets and like this untill get the final combination where all five names are
aaaa bbbb cccc dddd eeee
Thanks a lot
Use CALL LEXCOMB or CALL ALLCOMB
The CALL LEXCOMB routine generates all distinct combinations of the nonmissing values of n variables taken k at a time in lexicographic order. The CALL ALLCOMB routine generates all combinations of the values of n variables taken k at a time in a minimal change order.
The documentation has an example and here's a specific solution to your question.
data want;
*can load temporary array from dataset if required;
array x[5] $4 _temporary_ ('aaaa' 'bbbb' 'cccc' 'dddd' 'eeee');
*array for output;
array y(5) $4;
n=dim(x);
*loop overall all possible output ranges;
do k=1 to n;
*Determine number of combinations required;
ncomb=comb(n, k);
*Create all combinations;
do j=1 to ncomb;
*create the combination;
call lexcomb(j, k, of x[*]);
*Set all values to missing;
call missing(of y(*));
*Copy over the values to the array for output;
do i=1 to k;
y(i)=x(i);
end;
*output record;
output;
end;
end;
run;
proc print data=want;
run;
I looked up "aleatory", and I'm not sure what you really mean. My wikipedia look up defines aleatory (in music) as "determined in general but depends on chance in detail." But you say you want it "NOT ALEATORY". So you DON'T want "determined in general but depends on chance in detail". Sounds like you want a regular ordered list, with no randomization.
And that would be support by your sample list, under the title "want". But then, just before that list why do you say "and it can not be repeated like this:".
Please clarify.
Use CALL LEXCOMB or CALL ALLCOMB
The CALL LEXCOMB routine generates all distinct combinations of the nonmissing values of n variables taken k at a time in lexicographic order. The CALL ALLCOMB routine generates all combinations of the values of n variables taken k at a time in a minimal change order.
The documentation has an example and here's a specific solution to your question.
data want;
*can load temporary array from dataset if required;
array x[5] $4 _temporary_ ('aaaa' 'bbbb' 'cccc' 'dddd' 'eeee');
*array for output;
array y(5) $4;
n=dim(x);
*loop overall all possible output ranges;
do k=1 to n;
*Determine number of combinations required;
ncomb=comb(n, k);
*Create all combinations;
do j=1 to ncomb;
*create the combination;
call lexcomb(j, k, of x[*]);
*Set all values to missing;
call missing(of y(*));
*Copy over the values to the array for output;
do i=1 to k;
y(i)=x(i);
end;
*output record;
output;
end;
end;
run;
proc print data=want;
run;
This is awesome.
bs | y1 | y2 | y3 | y4 | y5 | n | k | ncomb | j | i |
1 | aaaa | 5 | 1 | 5 | 1 | 2 | ||||
2 | bbbb | 5 | 1 | 5 | 2 | 2 | ||||
3 | cccc | 5 | 1 | 5 | 3 | 2 | ||||
4 | dddd | 5 | 1 | 5 | 4 | 2 | ||||
5 | eeee | 5 | 1 | 5 | 5 | 2 | ||||
6 | aaaa | bbbb | 5 | 2 | 10 | 1 | 3 | |||
7 | aaaa | cccc | 5 | 2 | 10 | 2 | 3 | |||
8 | aaaa | dddd | 5 | 2 | 10 | 3 | 3 | |||
9 | aaaa | eeee | 5 | 2 | 10 | 4 | 3 | |||
10 | bbbb | cccc | 5 | 2 | 10 | 5 | 3 | |||
11 | bbbb | dddd | 5 | 2 | 10 | 6 | 3 | |||
12 | bbbb | eeee | 5 | 2 | 10 | 7 | 3 | |||
13 | cccc | dddd | 5 | 2 | 10 | 8 | 3 | |||
14 | cccc | eeee | 5 | 2 | 10 | 9 | 3 | |||
15 | dddd | eeee | 5 | 2 | 10 | 10 | 3 | |||
16 | aaaa | bbbb | cccc | 5 | 3 | 10 | 1 | 4 | ||
17 | aaaa | bbbb | dddd | 5 | 3 | 10 | 2 | 4 | ||
18 | aaaa | bbbb | eeee | 5 | 3 | 10 | 3 | 4 | ||
19 | aaaa | cccc | dddd | 5 | 3 | 10 | 4 | 4 | ||
20 | aaaa | cccc | eeee | 5 | 3 | 10 | 5 | 4 | ||
21 | aaaa | dddd | eeee | 5 | 3 | 10 | 6 | 4 | ||
22 | bbbb | cccc | dddd | 5 | 3 | 10 | 7 | 4 | ||
23 | bbbb | cccc | eeee | 5 | 3 | 10 | 8 | 4 | ||
24 | bbbb | dddd | eeee | 5 | 3 | 10 | 9 | 4 | ||
25 | cccc | dddd | eeee | 5 | 3 | 10 | 10 | 4 | ||
26 | aaaa | bbbb | cccc | dddd | 5 | 4 | 5 | 1 | 5 | |
27 | aaaa | bbbb | cccc | eeee | 5 | 4 | 5 | 2 | 5 | |
28 | aaaa | bbbb | dddd | eeee | 5 | 4 | 5 | 3 | 5 | |
29 | aaaa | cccc | dddd | eeee | 5 | 4 | 5 | 4 | 5 | |
30 | bbbb | cccc | dddd | eeee | 5 | 4 | 5 | 5 | 5 | |
31 | aaaa | bbbb | cccc | dddd | eeee | 5 | 5 | 1 | 1 |
Reeza's approach has all the bells and whistles, and is better than what I have below. Still, it's worth noting that you can get almost the same result with a simple program:
data want;
do name1='aaaa', ' ';
do name2='bbbb', ' ';
do name3='cccc', ' ';
do name4='dddd', ' ';
do name5='eeee', ' ';
output;
end; end; end; end; end;
run;
The name values don't always begin with NAME1, and you also get the empty set as a combination. But the programming is pretty easy.
Astounding, There are two simple way 1) data have; input x $; cards; aaaa bbbb cccc dddd eeee ; run; proc transpose data=have out=temp; var x; run; proc summary data=temp; class col:; output out=x; run; data want; set x; length want $ 200; want=catx('|',of col:); keep want; run; 2) data want; array z{5} $ ('aaaa' 'bbbb' 'cccc' 'dddd' 'eeee'); array x{5} ; length want $ 200; n=dim(x); k=-1; nsubs=2**n; do i=1 to nsubs; rc=graycode(k, of x{*}); call missing(want); do j=1 to n; if x{j}=1 then want=catx('|',want,z{j}); end; output; end; keep want ; run;
@Ksharp Graycode?
@Reeza ,
Yes. graycode() would give you all the combinations from 1 to n.
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.