<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Recursive or chained lookup with a data twist in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Recursive-or-chained-lookup-with-a-data-twist/m-p/876640#M346324</link>
    <description>&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;/*
You could combine 'employee_num' with 'id' and 'orig_id' to make a unique ID
*/
data x;
input employee_num id orig_id x1 $ x2 $ x3 $;
datalines;
1 11 . A B C
1 22 11 D E F
1 44 22 G H I
1 57 44 J K L
1 18 57 M N O
20 88 . W T U
20 98 88 V Z Y
;
RUN;

data key;
 set x;
 k=1000000000*employee_num+orig_id; 
 x=x1; output;
 x=x2; output;
 x=x3; output;

 k=1000000000*employee_num+id; 
 x=x1; output;
 x=x2; output;
 x=x3; output;
 keep k x;
run;




data have;
 set x(keep=employee_num id orig_id rename=(orig_id=from id=to));
 from=1000000000*employee_num+from; 
 to=1000000000*employee_num+to; 
 drop employee_num;
run;

data full;
  set have end=last;
  if _n_ eq 1 then do;
   declare hash h();
    h.definekey('node');
     h.definedata('node');
     h.definedone();
  end;
  output;
  node=from; h.replace();
  from=to; to=node;
  output;
  node=from; h.replace();
  if last then h.output(dataset:'node');
  drop node;
run;

data want(keep=node household);
declare hash ha(ordered:'a');
declare hiter hi('ha');
ha.definekey('count');
ha.definedata('last');
ha.definedone();
declare hash _ha(hashexp: 20);
_ha.definekey('key');
_ha.definedone();

if 0 then set full;
declare hash from_to(dataset:'full(where=(from is not missing and to is not missing))',hashexp:20,multidata:'y');
 from_to.definekey('from');
 from_to.definedata('to');
 from_to.definedone();

if 0 then set node;
declare hash no(dataset:'node');
declare hiter hi_no('no');
 no.definekey('node');
 no.definedata('node');
 no.definedone();
 

do while(hi_no.next()=0);
 household+1; output;
 count=1;
 key=node;_ha.add();
 last=node;ha.add();
 rc=hi.first();
 do while(rc=0);
   from=last;rx=from_to.find();
   do while(rx=0);
     key=to;ry=_ha.check();
      if ry ne 0 then do;
       node=to;output;rr=no.remove(key:node);
       key=to;_ha.add();
       count+1;
       last=to;ha.add();
      end;
      rx=from_to.find_next();
   end;
   rc=hi.next();
end;
ha.clear();_ha.clear();
end;
stop;
run;


proc sql ;
create table ancenstor as
select from as ancenstor from have(where=(from is not missing)) 
  where from not in (select to from have where from is not missing);

create table final_want as

select distinct household,x
 from want(where=(node is not missing)) as a left join key(where=(k is not missing)) as b
  on a.node=b.k
outer union corr
select household,put(mod(node,1000000000),best32. -l) as x,int(node/1000000000) as employee_num ,'ancenstor' as id from want where node in (select ancenstor from ancenstor)
order by 1,2
;
quit;

data final_want2;
 merge final_want(drop=employee_num) final_want(keep=employee_num household where=(employee_num is not missing));
 by household;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ksharp_0-1684495900099.png" style="width: 400px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/84127i016C38C8BD17B8C7/image-size/medium?v=v2&amp;amp;px=400" role="button" title="Ksharp_0-1684495900099.png" alt="Ksharp_0-1684495900099.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Fri, 19 May 2023 11:31:42 GMT</pubDate>
    <dc:creator>Ksharp</dc:creator>
    <dc:date>2023-05-19T11:31:42Z</dc:date>
    <item>
      <title>Recursive or chained lookup with a data twist</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Recursive-or-chained-lookup-with-a-data-twist/m-p/876355#M346256</link>
      <description>&lt;P&gt;I got the following HR data set with recursive IDs that all link back to an original ID. However, there are character variables that I also need to bring along with the recursive data set.&lt;/P&gt;&lt;P&gt;In the example below, the initial ID is 11, and the follow on ID 22 links via an originating ID 11 and so on. As you can see, they all link back to 11 via a recursive lookup.&amp;nbsp;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I've used the chained lookup code here &lt;A href="https://support.sas.com/kb/26/160.html" target="_blank"&gt;https://support.sas.com/kb/26/160.html&lt;/A&gt;, but can't get the variables to come along.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;data have;&lt;BR /&gt;input id orig_id x1 $ x2 $ x3 $;&lt;BR /&gt;datalines;&lt;BR /&gt;11 . A B C&lt;BR /&gt;22 11 D E F&lt;BR /&gt;44 22 G H I&lt;BR /&gt;57 44 J K L&lt;BR /&gt;18 57 M N O&lt;BR /&gt;;&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;DATA WANT;&lt;BR /&gt;INPUT id Y1 $ Y2 $ Y3 $ Y4 $ Y5 $ Y6 $ Y7 $ Y8 $ Y9 $ Y10 $ Y11$ Y12 $ Y13$ Y14 $ Y15 $;&lt;BR /&gt;datalines;&lt;BR /&gt;11 A B C D E F G H I J K L M N O&lt;BR /&gt;;&lt;BR /&gt;RUN;&lt;/P&gt;</description>
      <pubDate>Thu, 18 May 2023 01:17:33 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Recursive-or-chained-lookup-with-a-data-twist/m-p/876355#M346256</guid>
      <dc:creator>HR_coder123</dc:creator>
      <dc:date>2023-05-18T01:17:33Z</dc:date>
    </item>
    <item>
      <title>Re: Recursive or chained lookup with a data twist</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Recursive-or-chained-lookup-with-a-data-twist/m-p/876423#M346257</link>
      <description>&lt;P&gt;I can elaborate more on the question by providing an employee number, the IDs represent a case num for the employee and are all distinct.&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;data have;&lt;BR /&gt;input employee_num id orig_id x1 $ x2 $ x3 $;&lt;BR /&gt;datalines;&lt;BR /&gt;1 11 . A B C&lt;BR /&gt;1 22 11 D E F&lt;BR /&gt;1 44 22 G H I&lt;BR /&gt;1 57 44 J K L&lt;BR /&gt;1 18 57 M N O&lt;BR /&gt;2 88 . W T U&lt;BR /&gt;2 98 88 V Z Y&lt;BR /&gt;;&lt;BR /&gt;RUN;&lt;/P&gt;&lt;P&gt;DATA WANT;&lt;BR /&gt;INPUT employee_num id Y1 $ Y2 $ Y3 $ Y4 $ Y5 $ Y6 $ Y7 $ Y8 $ Y9 $ Y10 $ Y11$ Y12 $ Y13$ Y14 $ Y15 $;&lt;BR /&gt;datalines;&lt;BR /&gt;1 11 A B C D E F G H I J K L M N O&lt;BR /&gt;2 88 W T U V Z y . . . . . . . . .&lt;BR /&gt;;&lt;BR /&gt;RUN;&lt;/P&gt;</description>
      <pubDate>Thu, 18 May 2023 12:10:49 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Recursive-or-chained-lookup-with-a-data-twist/m-p/876423#M346257</guid>
      <dc:creator>HR_coder123</dc:creator>
      <dc:date>2023-05-18T12:10:49Z</dc:date>
    </item>
    <item>
      <title>Re: Recursive or chained lookup with a data twist</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Recursive-or-chained-lookup-with-a-data-twist/m-p/876437#M346260</link>
      <description>&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data x;
input id orig_id x1 $ x2 $ x3 $;
datalines;
11 . A B C
22 11 D E F
44 22 G H I
57 44 J K L
18 57 M N O
;

data key;
 set x;
 k=orig_id; 
 x=x1; output;
 x=x2; output;
 x=x3; output;

 k=id; 
 x=x1; output;
 x=x2; output;
 x=x3; output;
 keep k x;
run;




data have;
 set x(keep=id orig_id rename=(orig_id=from id=to));
run;

data full;
  set have end=last;
  if _n_ eq 1 then do;
   declare hash h();
    h.definekey('node');
     h.definedata('node');
     h.definedone();
  end;
  output;
  node=from; h.replace();
  from=to; to=node;
  output;
  node=from; h.replace();
  if last then h.output(dataset:'node');
  drop node;
run;


data want(keep=node household);
declare hash ha(ordered:'a');
declare hiter hi('ha');
ha.definekey('count');
ha.definedata('last');
ha.definedone();
declare hash _ha(hashexp: 20);
_ha.definekey('key');
_ha.definedone();

if 0 then set full;
declare hash from_to(dataset:'full(where=(from is not missing and to is not missing))',hashexp:20,multidata:'y');
 from_to.definekey('from');
 from_to.definedata('to');
 from_to.definedone();

if 0 then set node;
declare hash no(dataset:'node');
declare hiter hi_no('no');
 no.definekey('node');
 no.definedata('node');
 no.definedone();
 

do while(hi_no.next()=0);
 household+1; output;
 count=1;
 key=node;_ha.add();
 last=node;ha.add();
 rc=hi.first();
 do while(rc=0);
   from=last;rx=from_to.find();
   do while(rx=0);
     key=to;ry=_ha.check();
      if ry ne 0 then do;
       node=to;output;rr=no.remove(key:node);
       key=to;_ha.add();
       count+1;
       last=to;ha.add();
      end;
      rx=from_to.find_next();
   end;
   rc=hi.next();
end;
ha.clear();_ha.clear();
end;
stop;
run;


proc sql ;
create table ancenstor as
select from as ancenstor from have(where=(from is not missing)) 
  where from not in (select to from have where from is not missing);

create table final_want as

select distinct household,x
 from want(where=(node is not missing)) as a left join key(where=(k is not missing)) as b
  on a.node=b.k
union
select household,put(node,best. -l) from want where node in (select ancenstor from ancenstor)
;
quit;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ksharp_0-1684414636403.png" style="width: 400px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/84094iB668BE3437896CF9/image-size/medium?v=v2&amp;amp;px=400" role="button" title="Ksharp_0-1684414636403.png" alt="Ksharp_0-1684414636403.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 18 May 2023 12:57:25 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Recursive-or-chained-lookup-with-a-data-twist/m-p/876437#M346260</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2023-05-18T12:57:25Z</dc:date>
    </item>
    <item>
      <title>Re: Recursive or chained lookup with a data twist</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Recursive-or-chained-lookup-with-a-data-twist/m-p/876461#M346263</link>
      <description>&lt;P&gt;Will this work with my follow up example, sorry I changed the original example to include an employee_num, and pull the ID? I have yet to run through the code you supplied, but it's much appreciated.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;data have;&lt;BR /&gt;input employee_num id orig_id x1 $ x2 $ x3 $;&lt;BR /&gt;datalines;&lt;BR /&gt;1 11 . A B C&lt;BR /&gt;1 22 11 D E F&lt;BR /&gt;1 44 22 G H I&lt;BR /&gt;1 57 44 J K L&lt;BR /&gt;1 18 57 M N O&lt;BR /&gt;2 88 . W T U&lt;BR /&gt;2 98 88 V Z Y&lt;BR /&gt;;&lt;BR /&gt;RUN;&lt;/P&gt;&lt;P&gt;DATA WANT;&lt;BR /&gt;INPUT employee_num id Y1 $ Y2 $ Y3 $ Y4 $ Y5 $ Y6 $ Y7 $ Y8 $ Y9 $ Y10 $ Y11$ Y12 $ Y13$ Y14 $ Y15 $;&lt;BR /&gt;datalines;&lt;BR /&gt;1 11 A B C D E F G H I J K L M N O&lt;BR /&gt;2 88 W T U V Z y . . . . . . . . .&lt;BR /&gt;;&lt;BR /&gt;RUN;&lt;/P&gt;</description>
      <pubDate>Thu, 18 May 2023 14:02:57 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Recursive-or-chained-lookup-with-a-data-twist/m-p/876461#M346263</guid>
      <dc:creator>HR_coder123</dc:creator>
      <dc:date>2023-05-18T14:02:57Z</dc:date>
    </item>
    <item>
      <title>Re: Recursive or chained lookup with a data twist</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Recursive-or-chained-lookup-with-a-data-twist/m-p/876640#M346324</link>
      <description>&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;/*
You could combine 'employee_num' with 'id' and 'orig_id' to make a unique ID
*/
data x;
input employee_num id orig_id x1 $ x2 $ x3 $;
datalines;
1 11 . A B C
1 22 11 D E F
1 44 22 G H I
1 57 44 J K L
1 18 57 M N O
20 88 . W T U
20 98 88 V Z Y
;
RUN;

data key;
 set x;
 k=1000000000*employee_num+orig_id; 
 x=x1; output;
 x=x2; output;
 x=x3; output;

 k=1000000000*employee_num+id; 
 x=x1; output;
 x=x2; output;
 x=x3; output;
 keep k x;
run;




data have;
 set x(keep=employee_num id orig_id rename=(orig_id=from id=to));
 from=1000000000*employee_num+from; 
 to=1000000000*employee_num+to; 
 drop employee_num;
run;

data full;
  set have end=last;
  if _n_ eq 1 then do;
   declare hash h();
    h.definekey('node');
     h.definedata('node');
     h.definedone();
  end;
  output;
  node=from; h.replace();
  from=to; to=node;
  output;
  node=from; h.replace();
  if last then h.output(dataset:'node');
  drop node;
run;

data want(keep=node household);
declare hash ha(ordered:'a');
declare hiter hi('ha');
ha.definekey('count');
ha.definedata('last');
ha.definedone();
declare hash _ha(hashexp: 20);
_ha.definekey('key');
_ha.definedone();

if 0 then set full;
declare hash from_to(dataset:'full(where=(from is not missing and to is not missing))',hashexp:20,multidata:'y');
 from_to.definekey('from');
 from_to.definedata('to');
 from_to.definedone();

if 0 then set node;
declare hash no(dataset:'node');
declare hiter hi_no('no');
 no.definekey('node');
 no.definedata('node');
 no.definedone();
 

do while(hi_no.next()=0);
 household+1; output;
 count=1;
 key=node;_ha.add();
 last=node;ha.add();
 rc=hi.first();
 do while(rc=0);
   from=last;rx=from_to.find();
   do while(rx=0);
     key=to;ry=_ha.check();
      if ry ne 0 then do;
       node=to;output;rr=no.remove(key:node);
       key=to;_ha.add();
       count+1;
       last=to;ha.add();
      end;
      rx=from_to.find_next();
   end;
   rc=hi.next();
end;
ha.clear();_ha.clear();
end;
stop;
run;


proc sql ;
create table ancenstor as
select from as ancenstor from have(where=(from is not missing)) 
  where from not in (select to from have where from is not missing);

create table final_want as

select distinct household,x
 from want(where=(node is not missing)) as a left join key(where=(k is not missing)) as b
  on a.node=b.k
outer union corr
select household,put(mod(node,1000000000),best32. -l) as x,int(node/1000000000) as employee_num ,'ancenstor' as id from want where node in (select ancenstor from ancenstor)
order by 1,2
;
quit;

data final_want2;
 merge final_want(drop=employee_num) final_want(keep=employee_num household where=(employee_num is not missing));
 by household;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ksharp_0-1684495900099.png" style="width: 400px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/84127i016C38C8BD17B8C7/image-size/medium?v=v2&amp;amp;px=400" role="button" title="Ksharp_0-1684495900099.png" alt="Ksharp_0-1684495900099.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 19 May 2023 11:31:42 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Recursive-or-chained-lookup-with-a-data-twist/m-p/876640#M346324</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2023-05-19T11:31:42Z</dc:date>
    </item>
    <item>
      <title>Re: Recursive or chained lookup with a data twist</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Recursive-or-chained-lookup-with-a-data-twist/m-p/876664#M346327</link>
      <description>&lt;P&gt;This is perfect, thanks so much!&lt;/P&gt;</description>
      <pubDate>Fri, 19 May 2023 13:42:25 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Recursive-or-chained-lookup-with-a-data-twist/m-p/876664#M346327</guid>
      <dc:creator>HR_coder123</dc:creator>
      <dc:date>2023-05-19T13:42:25Z</dc:date>
    </item>
  </channel>
</rss>

