Sorry.
My code above is wrong.But I am still fight for it because I am very very interested with your problem.The following is correct code I believed !!!!!!!
[pre]
data temp(where=(boss is not missing));
input boss $ sub $;
cards;
Jim Kate
Lisa Anna
Dave Lisa
Dave Erik
Dave Jim
Dave Peter
Anna Mary
Anna Ben
Anna Lisa
Erik Anna
Erik Dave
. Dave
;
run;
proc sort data=temp;
by boss;
run;
data temp_unique temp_dup;
set temp;
by boss;
if not(first.boss and last.boss) then output temp_dup;
else output temp_unique;
run;
data want;
declare hash ha (hashexp:10);
ha.definekey('_boss');
ha.definedata('sub');
ha.definedone();
do until(last);
set temp_unique(rename=(boss=_boss)) end=last;
ha.add();
end;
do until(_last);
set temp_unique end=_last;
output;
_boss=boss;
do until(rc ne 0 or count gt 10000);
/* 'count gt 10000' is to avoid dead loop ,Example: Dave->Jim Jim->Dave*/
count+1;
rc=ha.find();
if rc = 0 then output;
_boss=sub;
end;
end;
drop _boss rc;
run;
options mprint;
%macro all_comb;
proc sort data=temp_dup;
by boss;
run;
data order;
set temp_dup;
by boss;
retain start;
if first.boss then start= _n_;
if last.boss then do; end= _n_; output; end;
run;
data _null_;
set order end=last;
call symputx(cats('do',_n_),'do '||boss||'='||strip(start)||' to '||strip(end)||' ;' );
call symputx(cats('set',_n_),'set temp_dup point='||boss||'; output;');
call symputx(cats('end',_n_),'end;');
if last then call symputx('nobs',_n_);
run;
/* To get all the combination of boss who has duplicated value*/
data comb;
%do i=1 %to &nobs;
&&do&i
%end;
count+1;
%do j=1 %to &nobs;
&&set&j
%end;
%do k=1 %to &nobs;
&&end&k
%end;
stop;
run;
%mend all_comb;
%all_comb
data _null_;
set Comb end=last;
if last then call symputx('count',count);
run;
%put _user_;
%macro loop;
%do i=1 %to &count ;
data single;
set comb;
if count eq &i;
run;
data middle;
set temp_unique single;
run;
data want_middle;
declare hash ha (hashexp:10);
ha.definekey('_boss');
ha.definedata('sub');
ha.definedone();
do until(last);
set middle(rename=(boss=_boss)) end=last;
ha.add();
end;
do until(_last);
set middle end=_last;
output;
_boss=boss;
do until(rc ne 0 or count gt 10000);
count+1;
rc=ha.find();
if rc = 0 then output;
_boss=sub;
end;
end;
drop _boss rc;
run;
proc append base=want data=want_middle force;
run;
%end;
%mend loop;
%loop
proc sort data=want out=final_want(drop=count) nodupkey;
by boss sub;
run;
[/pre]
And I also consider an problem about your question
Namely, dead loop.For example: Dave->Jim Jim->Dave
Cheers!!!!
Ksharp
Message was edited by: Ksharp
Message was edited by: Ksharp
... View more