<?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: Is there a SAS procedure that will create a network table in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Is-there-a-SAS-procedure-that-will-create-a-network-table/m-p/963101#M375266</link>
    <description>If you know the total shares for each company you can compute a fraction factor for each tier of secondary, tertiary and n-ary ownership.</description>
    <pubDate>Tue, 01 Apr 2025 10:39:17 GMT</pubDate>
    <dc:creator>RichardAD</dc:creator>
    <dc:date>2025-04-01T10:39:17Z</dc:date>
    <item>
      <title>Is there a SAS procedure that will create a network table</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Is-there-a-SAS-procedure-that-will-create-a-network-table/m-p/962902#M375224</link>
      <description>&lt;P&gt;Hi&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I have a table where each row contains columns that have 'companies' and 'share owners' and the number of shares owned.&amp;nbsp; Any owner can have multiple rows of companies that they have shares in, and many owners may have shares in many companies.&amp;nbsp; Also companies can have shares in other companies as owners. This is a very large table with over 10 million rows.&amp;nbsp; The Owner_id (say 1002) in the first row is the same entity as the Company_id in the second row, so therefore owner_id 1002 is linked to company_id&amp;nbsp; 1001, which is linked to company 1003) and company_id 1002 is linked to owner_id 1011, which also has shares in company_id 1004, and so on.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The 'have' data looks as follows:&lt;/P&gt;&lt;P&gt;Company_id $4. Owner_id $4. Shares 8.&lt;/P&gt;&lt;TABLE border="0" cellspacing="0" cellpadding="0"&gt;&lt;TBODY&gt;&lt;TR&gt;&lt;TD&gt;Company_id&lt;/TD&gt;&lt;TD&gt;Owner_id&lt;/TD&gt;&lt;TD&gt;Shares&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;1001&lt;/TD&gt;&lt;TD&gt;1002&lt;/TD&gt;&lt;TD&gt;100&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;1002&lt;/TD&gt;&lt;TD&gt;1011&lt;/TD&gt;&lt;TD&gt;400&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;1003&lt;/TD&gt;&lt;TD&gt;1001&lt;/TD&gt;&lt;TD&gt;2500&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;1004&lt;/TD&gt;&lt;TD&gt;1011&lt;/TD&gt;&lt;TD&gt;1000&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;1005&lt;/TD&gt;&lt;TD&gt;1012&lt;/TD&gt;&lt;TD&gt;800&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;1006&lt;/TD&gt;&lt;TD&gt;1007&lt;/TD&gt;&lt;TD&gt;120&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;1007&lt;/TD&gt;&lt;TD&gt;1013&lt;/TD&gt;&lt;TD&gt;450&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;1008&lt;/TD&gt;&lt;TD&gt;1015&lt;/TD&gt;&lt;TD&gt;250&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;1009&lt;/TD&gt;&lt;TD&gt;1014&lt;/TD&gt;&lt;TD&gt;150&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;1010&lt;/TD&gt;&lt;TD&gt;1015&lt;/TD&gt;&lt;TD&gt;4500&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;1020&lt;/TD&gt;&lt;TD&gt;1001&lt;/TD&gt;&lt;TD&gt;25000&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;1021&lt;/TD&gt;&lt;TD&gt;1020&lt;/TD&gt;&lt;TD&gt;100000&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;What I would like to create&amp;nbsp; is a table for input to another process that has, for each owner_id,&amp;nbsp; each company they have shares in (as above) but also each company that they have shares in that has shares in other companies (secondary owners).&amp;nbsp; I'm aware that with such a larger table the output could be in the billions of rows, so I was thinking to limit the number of rows by filtering the number of shares for secondary owners say to 1000 shares to allow, for example, linking ACME (1002)&amp;nbsp; having 100 shares in Ford (1001), but not including Ford (1001) having 25,000 shares in McDonalds (1020), which may have 100,000 shares in Microsoft (1021) etc).&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;So the output for ACME might be:&lt;/P&gt;&lt;TABLE border="0" cellspacing="0" cellpadding="0"&gt;&lt;TBODY&gt;&lt;TR&gt;&lt;TD&gt;Company_id&lt;/TD&gt;&lt;TD&gt;Owner_id&lt;/TD&gt;&lt;TD&gt;Shares&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;1001&lt;/TD&gt;&lt;TD&gt;1002&lt;/TD&gt;&lt;TD&gt;100&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;1002&lt;/TD&gt;&lt;TD&gt;1011&lt;/TD&gt;&lt;TD&gt;400&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;And so on.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;At present I'm testing assumptions on a table with 10,000 rows, but I am wondering if something like proc cluster, proc tree or proc distance of any similar procs might give me what I want (even if I have to eliminate the large corporate holdings myself).&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Hope this is clear enough for assistance,&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thanks for any advice.&lt;/P&gt;</description>
      <pubDate>Sat, 29 Mar 2025 08:29:07 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Is-there-a-SAS-procedure-that-will-create-a-network-table/m-p/962902#M375224</guid>
      <dc:creator>gordononline</dc:creator>
      <dc:date>2025-03-29T08:29:07Z</dc:date>
    </item>
    <item>
      <title>Re: Is there a SAS procedure that will create a network table</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Is-there-a-SAS-procedure-that-will-create-a-network-table/m-p/963032#M375246</link>
      <description>&lt;P&gt;Hello ,&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I think ... if you search these SAS communities&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;for&amp;nbsp;grandparent-parent-child hierarchy or&lt;/LI&gt;
&lt;LI&gt;for&amp;nbsp;grandparent-parent-child relationships or&lt;/LI&gt;
&lt;LI&gt;for&amp;nbsp;ancestor - descendent hierarchy&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;... that you will find what you are looking for.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Try f.e. (Google search) :&lt;/P&gt;
&lt;UL class="lia-list-style-type-square"&gt;
&lt;LI&gt;grandparent parent child hierarchy&amp;nbsp;&lt;STRONG&gt;site:communities.sas.com&lt;/STRONG&gt;&lt;BR /&gt;or&amp;nbsp;&lt;/LI&gt;
&lt;LI&gt;parent child hierarchy&amp;nbsp;&lt;STRONG&gt;site:communities.sas.com&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;BR /&gt;BR, Koen&lt;/P&gt;</description>
      <pubDate>Mon, 31 Mar 2025 17:10:51 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Is-there-a-SAS-procedure-that-will-create-a-network-table/m-p/963032#M375246</guid>
      <dc:creator>sbxkoenk</dc:creator>
      <dc:date>2025-03-31T17:10:51Z</dc:date>
    </item>
    <item>
      <title>Re: Is there a SAS procedure that will create a network table</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Is-there-a-SAS-procedure-that-will-create-a-network-table/m-p/963074#M375262</link>
      <description>&lt;P&gt;&lt;FONT color="#000000"&gt;1)&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color="#000000"&gt;Yes. But you need to have module SAS/OR . Here is an example:&lt;/FONT&gt;&lt;/P&gt;
&lt;PRE&gt;data have(rename=(Company_id=from Owner_id=to));
infile cards expandtabs truncover;
input Company_id	Owner_id	Shares;
cards;
1001	1002	100
1002	1011	400
1003	1001	2500
1004	1011	1000
1005	1012	800
1006	1007	120
1007	1013	450
1008	1015	250
1009	1014	150
1010	1015	4500
1020	1001	25000
1021	1020	100000
;


proc optnet data_links=have out_nodes=want GRAPH_DIRECTION=UNDIRECTED;
data_links_var from=from to=to;
concomp;
run;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;FONT color="#000000"&gt;2)&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color="#000000"&gt;If you don't have SAS/OR ,try this one (But you need lots and lots of memory within your computer):&lt;/FONT&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;FONT color="#000000"&gt;data have;
infile cards expandtabs truncover;
input Company_id	Owner_id	Shares;
cards;
1001	1002	100
1002	1011	400
1003	1001	2500
1004	1011	1000
1005	1012	800
1006	1007	120
1007	1013	450
1008	1015	250
1009	1014	150
1010	1015	4500
1020	1001	25000
1021	1020	100000
;


data full;
  set have(rename=(Company_id=from Owner_id=to)) ;
  output;
  node=from; from=to; to=node;
  output;
  keep from to;
run;

&lt;FONT color="#FF0000"&gt;&lt;STRONG&gt;data node; /*the ID you want to search*/&lt;/STRONG&gt;&lt;/FONT&gt;
input node;
cards;
1002
;


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;


data final_want;
 if _n_=1 then do;
  if 0 then set want(keep=node);
  declare hash h(dataset:'want(keep=node)');
  h.definekey('node');
  h.definedone();
 end;
set have;
if (h.check(key:Company_id)=0 or h.check(key:Owner_id)=0) and Shares &amp;lt; 1000 ;
drop node;
run;&lt;/FONT&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;FONT color="#000000"&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/P&gt;</description>
      <pubDate>Tue, 01 Apr 2025 03:10:55 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Is-there-a-SAS-procedure-that-will-create-a-network-table/m-p/963074#M375262</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2025-04-01T03:10:55Z</dc:date>
    </item>
    <item>
      <title>Re: Is there a SAS procedure that will create a network table</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Is-there-a-SAS-procedure-that-will-create-a-network-table/m-p/963101#M375266</link>
      <description>If you know the total shares for each company you can compute a fraction factor for each tier of secondary, tertiary and n-ary ownership.</description>
      <pubDate>Tue, 01 Apr 2025 10:39:17 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Is-there-a-SAS-procedure-that-will-create-a-network-table/m-p/963101#M375266</guid>
      <dc:creator>RichardAD</dc:creator>
      <dc:date>2025-04-01T10:39:17Z</dc:date>
    </item>
    <item>
      <title>Re: Is there a SAS procedure that will create a network table</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Is-there-a-SAS-procedure-that-will-create-a-network-table/m-p/963344#M375328</link>
      <description>If there are multiple paths from an owner id to a company id, how many observations do you want in the output dataset?  One obs, or one obs per path?  And if the latter, do you also want measures of the "length" of each path?  There are, of course, other possibilities if you have other info available, such as total shares of each company being publicly traded.</description>
      <pubDate>Thu, 03 Apr 2025 16:47:25 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Is-there-a-SAS-procedure-that-will-create-a-network-table/m-p/963344#M375328</guid>
      <dc:creator>mkeintz</dc:creator>
      <dc:date>2025-04-03T16:47:25Z</dc:date>
    </item>
  </channel>
</rss>

