BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.

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

1 ACCEPTED SOLUTION

Accepted Solutions
Reeza
Super User

Use CALL LEXCOMB or CALL ALLCOMB 

http://support.sas.com/documentation/cdl/en/lefunctionsref/69762/HTML/default/viewer.htm#p0yvzzxdzou...

 

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;

 

View solution in original post

8 REPLIES 8
mkeintz
PROC Star

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.

 

 

--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------
jonatan_velarde
Pyrite | Level 9
Thanks in advance for your point .

Yes, i need a regular ordered list in duplet, triples and quadruplets as was shown in the want example.

IF you can help me i would really apreciate

Regards
Reeza
Super User

Use CALL LEXCOMB or CALL ALLCOMB 

http://support.sas.com/documentation/cdl/en/lefunctionsref/69762/HTML/default/viewer.htm#p0yvzzxdzou...

 

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;

 

jonatan_velarde
Pyrite | Level 9

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  
Astounding
PROC Star

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.

Ksharp
Super User
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;




Reeza
Super User

@Ksharp Graycode?

Ksharp
Super User

@Reeza ,

Yes. graycode() would give you all the combinations from 1 to n.

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

How to Concatenate Values

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 8 replies
  • 2044 views
  • 10 likes
  • 5 in conversation