<?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: Lookup Values from a Rate Matrix Table in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185433#M35190</link>
    <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;The multidata is new at 9.2. &lt;/P&gt;&lt;P&gt;9.1.3 is already very old (2008), grrr why is lcm of SAS that bad as there is no license cost constraint. Yes it is a personal frustration.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I think that drops the hash approach. We are still having:&lt;/P&gt;&lt;P&gt;- a format usage I am thinking on:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; The date delivering a format name,,, the delivered format apply on the balance value&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; How many recodes (formats) do you have/expect&amp;nbsp;&amp;nbsp; (asked this before) &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; This is quite a unique but simple approach inputn usage. &lt;A class="active_link" href="http://support.sas.com/documentation/cdl/en/lefunctionsref/67398/HTML/default/viewer.htm#n1xdirhugd30qcn1szvchqcss3wv.htm" title="http://support.sas.com/documentation/cdl/en/lefunctionsref/67398/HTML/default/viewer.htm#n1xdirhugd30qcn1szvchqcss3wv.htm"&gt;SAS(R) 9.4 Functions and CALL Routines: Reference, Third Edition&lt;/A&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The code for this goes like:&lt;/P&gt;&lt;P&gt;/* ----------------------- */&lt;BR /&gt;proc format;&lt;BR /&gt; value recode_dt (default=16 max=32)&lt;BR /&gt; '01jan2014'd - '01feb2014'd = "rcd_1v." &lt;BR /&gt; '01feb2014'd - '01mar2014'd = "rcd_2v."&lt;BR /&gt;&amp;nbsp; other= "dummy" ;&lt;BR /&gt; invalue dummy &lt;BR /&gt;&amp;nbsp; other=. ; /* undefined recode */&amp;nbsp;&amp;nbsp; &lt;BR /&gt; invalue rcd_1v&lt;BR /&gt;&amp;nbsp; 0-&amp;lt;1000 = 0.00&amp;nbsp;&amp;nbsp; &lt;BR /&gt;&amp;nbsp; 1000-&amp;lt;10000 = 0.05&lt;BR /&gt;&amp;nbsp; 10000-&amp;lt;100000 = 0.10 &lt;BR /&gt;&amp;nbsp; 100000-High&amp;nbsp;&amp;nbsp; = 0.15 &lt;BR /&gt;&amp;nbsp; other=. ; /* undefined recode */&lt;BR /&gt; invalue rcd_2v&lt;BR /&gt;&amp;nbsp; 0-&amp;lt;1000 = 0.05&amp;nbsp;&amp;nbsp; &lt;BR /&gt;&amp;nbsp; 1000-&amp;lt;10000 = 0.1&lt;BR /&gt;&amp;nbsp; 10000-&amp;lt;100000 = 0.15 &lt;BR /&gt;&amp;nbsp; 100000-High&amp;nbsp;&amp;nbsp; = 0.20 &lt;BR /&gt;&amp;nbsp; other=. ; /* undefined recode */&lt;BR /&gt;run;&lt;/P&gt;&lt;P&gt;data result ;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; set transaction;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; attrib int_rate format=percent. length=4&amp;nbsp;&amp;nbsp; int_recod length=$8 ;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; int_recod=put(effective_date,recode_dt.);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; int_rate=inputn(put(balance,12.), int_recod) ; &lt;BR /&gt;run;&lt;/P&gt;&lt;P&gt;&lt;BR /&gt; &lt;/P&gt;&lt;P&gt;- a balanced merge on the data using a datastep.&amp;nbsp;&amp;nbsp; &lt;BR /&gt;&amp;nbsp; The assumption is sorted sas datasets&lt;/P&gt;&lt;P&gt;Need a sample ??&amp;nbsp; (there are more ways merge by, point usage)&lt;BR /&gt;SASfile usage to get the dataset into memory&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;SQL is probably slow as it does a full join and than selecting what is needed. your 100mb is blown up first. (Cartesian)&amp;nbsp; &lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;BR /&gt; &lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
    <pubDate>Thu, 04 Sep 2014 13:03:09 GMT</pubDate>
    <dc:creator>jakarman</dc:creator>
    <dc:date>2014-09-04T13:03:09Z</dc:date>
    <item>
      <title>Lookup Values from a Rate Matrix Table</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185430#M35187</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Guys,&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I am presently working with a matrix table containing a lo-date a lo-amount and an interest rate.&amp;nbsp; There are 4,000,000 observations within this table.&amp;nbsp; I need to perform a look up on the matrix table based on the effective date of the transaction and the current balance in my transaction data.&amp;nbsp; The original code uses SQL to perform this look up and although it works it takes over 2 hours to complete.&amp;nbsp; Can someone offer some insight into a more effecient method obtaining the desired outcome?&amp;nbsp; I have added indexes and we are seeing a small amount of improvement, but no where near what is required.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The logic is &lt;STRONG&gt;if Lo_Date &amp;lt;= &lt;STRONG&gt;Effective_Date and &lt;STRONG&gt;Lo_Amount &amp;lt;= &lt;STRONG&gt;Balance then Int_Rate&lt;/STRONG&gt;&lt;/STRONG&gt;&lt;/STRONG&gt;&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Thank you very much for your help.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;TABLE border="0" cellpadding="0" cellspacing="0" style="WIDTH: 236px;"&gt;&lt;TBODY&gt;&lt;TR&gt;&lt;TD class="xl67" height="20" width="99"&gt;&lt;STRONG&gt;Matrix_Table&lt;/STRONG&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD height="20"&gt;&lt;STRONG&gt;Lo_Date&lt;/STRONG&gt;&lt;/TD&gt;&lt;TD&gt;&lt;STRONG&gt;Lo_Amount&lt;/STRONG&gt;&lt;/TD&gt;&lt;TD&gt;&lt;STRONG&gt;Int_Rate&lt;/STRONG&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;1/01/2014&lt;/TD&gt;&lt;TD align="right"&gt;0&lt;/TD&gt;&lt;TD align="right" class="xl66"&gt;0%&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;1/01/2014&lt;/TD&gt;&lt;TD align="right"&gt;1000&lt;/TD&gt;&lt;TD align="right" class="xl66"&gt;5%&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;1/01/2014&lt;/TD&gt;&lt;TD align="right"&gt;10000&lt;/TD&gt;&lt;TD align="right" class="xl66"&gt;10%&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;1/01/2014&lt;/TD&gt;&lt;TD align="right"&gt;100000&lt;/TD&gt;&lt;TD align="right" class="xl66"&gt;15%&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;1/02/2014&lt;/TD&gt;&lt;TD align="right"&gt;0&lt;/TD&gt;&lt;TD align="right" class="xl66"&gt;5%&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;1/02/2014&lt;/TD&gt;&lt;TD align="right"&gt;1000&lt;/TD&gt;&lt;TD align="right" class="xl66"&gt;10%&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;1/02/2014&lt;/TD&gt;&lt;TD align="right"&gt;10000&lt;/TD&gt;&lt;TD align="right" class="xl66"&gt;15%&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;1/02/2014&lt;/TD&gt;&lt;TD align="right"&gt;100000&lt;/TD&gt;&lt;TD align="right" class="xl66"&gt;20%&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;P&gt;&lt;/P&gt;&lt;TABLE border="0" cellpadding="0" cellspacing="0" style="WIDTH: 177px;"&gt;&lt;TBODY&gt;&lt;TR&gt;&lt;TD class="xl67" height="20" width="99"&gt;&lt;STRONG&gt;Transaction_Table&lt;/STRONG&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD height="20"&gt;&lt;STRONG&gt;Effective_Date&lt;/STRONG&gt;&lt;/TD&gt;&lt;TD&gt;&lt;STRONG&gt;Balance&lt;/STRONG&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;15/01/2014&lt;/TD&gt;&lt;TD align="right"&gt;11000&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;15/01/2014&lt;/TD&gt;&lt;TD align="right"&gt;1000&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;15/01/2014&lt;/TD&gt;&lt;TD align="right"&gt;15000&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;15/01/2014&lt;/TD&gt;&lt;TD align="right"&gt;110000&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;15/01/2014&lt;/TD&gt;&lt;TD align="right"&gt;900&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;15/01/2014&lt;/TD&gt;&lt;TD align="right"&gt;100&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;15/01/2014&lt;/TD&gt;&lt;TD align="right"&gt;6000&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;15/01/2014&lt;/TD&gt;&lt;TD align="right"&gt;100001&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;15/01/2014&lt;/TD&gt;&lt;TD align="right"&gt;99999&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;15/02/2014&lt;/TD&gt;&lt;TD align="right"&gt;11000&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;15/02/2014&lt;/TD&gt;&lt;TD align="right"&gt;1000&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;15/02/2014&lt;/TD&gt;&lt;TD align="right"&gt;15000&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;15/02/2014&lt;/TD&gt;&lt;TD align="right"&gt;110000&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;15/02/2014&lt;/TD&gt;&lt;TD align="right"&gt;900&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;15/02/2014&lt;/TD&gt;&lt;TD align="right"&gt;100&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;15/02/2014&lt;/TD&gt;&lt;TD align="right"&gt;6000&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;15/02/2014&lt;/TD&gt;&lt;TD align="right"&gt;100001&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;15/02/2014&lt;/TD&gt;&lt;TD align="right"&gt;99999&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;P&gt;&lt;/P&gt;&lt;TABLE border="0" cellpadding="0" cellspacing="0" style="WIDTH: 236px;"&gt;&lt;TBODY&gt;&lt;TR&gt;&lt;TD class="xl67" height="20" width="99"&gt;&lt;STRONG&gt;Result_Table&lt;/STRONG&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD height="20"&gt;&lt;STRONG&gt;Effective_Date&lt;/STRONG&gt;&lt;/TD&gt;&lt;TD&gt;&lt;STRONG&gt;Balance&lt;/STRONG&gt;&lt;/TD&gt;&lt;TD&gt;&lt;STRONG&gt;Int_Rate&lt;/STRONG&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;15/01/2014&lt;/TD&gt;&lt;TD align="right"&gt;11000&lt;/TD&gt;&lt;TD align="right" class="xl66"&gt;10%&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;15/01/2014&lt;/TD&gt;&lt;TD align="right"&gt;1000&lt;/TD&gt;&lt;TD align="right" class="xl66"&gt;5%&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;15/01/2014&lt;/TD&gt;&lt;TD align="right"&gt;15000&lt;/TD&gt;&lt;TD align="right" class="xl66"&gt;10%&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;15/01/2014&lt;/TD&gt;&lt;TD align="right"&gt;110000&lt;/TD&gt;&lt;TD align="right" class="xl66"&gt;15%&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;15/01/2014&lt;/TD&gt;&lt;TD align="right"&gt;900&lt;/TD&gt;&lt;TD align="right" class="xl66"&gt;0%&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;15/01/2014&lt;/TD&gt;&lt;TD align="right"&gt;100&lt;/TD&gt;&lt;TD align="right" class="xl66"&gt;0%&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;15/01/2014&lt;/TD&gt;&lt;TD align="right"&gt;6000&lt;/TD&gt;&lt;TD align="right" class="xl66"&gt;5%&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;15/01/2014&lt;/TD&gt;&lt;TD align="right"&gt;100001&lt;/TD&gt;&lt;TD align="right" class="xl66"&gt;15%&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;15/01/2014&lt;/TD&gt;&lt;TD align="right"&gt;99999&lt;/TD&gt;&lt;TD align="right" class="xl66"&gt;10%&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;15/02/2014&lt;/TD&gt;&lt;TD align="right"&gt;11000&lt;/TD&gt;&lt;TD align="right" class="xl66"&gt;15%&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;15/02/2014&lt;/TD&gt;&lt;TD align="right"&gt;1000&lt;/TD&gt;&lt;TD align="right" class="xl66"&gt;10%&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;15/02/2014&lt;/TD&gt;&lt;TD align="right"&gt;15000&lt;/TD&gt;&lt;TD align="right" class="xl66"&gt;15%&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;15/02/2014&lt;/TD&gt;&lt;TD align="right"&gt;110000&lt;/TD&gt;&lt;TD align="right" class="xl66"&gt;20%&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;15/02/2014&lt;/TD&gt;&lt;TD align="right"&gt;900&lt;/TD&gt;&lt;TD align="right" class="xl66"&gt;5%&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;15/02/2014&lt;/TD&gt;&lt;TD align="right"&gt;100&lt;/TD&gt;&lt;TD align="right" class="xl66"&gt;5%&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;15/02/2014&lt;/TD&gt;&lt;TD align="right"&gt;6000&lt;/TD&gt;&lt;TD align="right" class="xl66"&gt;10%&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;15/02/2014&lt;/TD&gt;&lt;TD align="right"&gt;100001&lt;/TD&gt;&lt;TD align="right" class="xl66"&gt;20%&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD align="right" class="xl65" height="20"&gt;15/02/2014&lt;/TD&gt;&lt;TD align="right"&gt;99999&lt;/TD&gt;&lt;TD align="right" class="xl66"&gt;15%&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 04 Sep 2014 04:33:36 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185430#M35187</guid>
      <dc:creator>Scott_Mitchell</dc:creator>
      <dc:date>2014-09-04T04:33:36Z</dc:date>
    </item>
    <item>
      <title>Re: Lookup Values from a Rate Matrix Table</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185431#M35188</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;There are several techniques to do a table lookup: &lt;A href="http://www2.sas.com/proceedings/forum2008/095-2008.pdf" title="http://www2.sas.com/proceedings/forum2008/095-2008.pdf"&gt;http://www2.sas.com/proceedings/forum2008/095-2008.pdf&lt;/A&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The problem is: you have two values date/value that is giving one new value.&lt;BR /&gt;This limits to some techniques. All is depending how big the dataset 4M records is compared to your system When this is those 3 variables 2 numbers and a string of 4 (?) it is still below 100MB. Not shocking big should&amp;nbsp; fit into memory. A Hash technique would be the most efficient one.&amp;nbsp; &lt;BR /&gt;Something to work out&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;reviews question:&lt;BR /&gt;- the recoding in percentages it several classes doe only makes sense by a table when they are getting different in time&lt;BR /&gt;&amp;nbsp; When there are several recode list of the values that are different in time and that list is limted by number of 10 or 20 or automated bij let us say 1000.&lt;/P&gt;&lt;P&gt;&amp;nbsp; It is making more sense to define those list as a format and select each of those formats as a time dependent variable.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;With hashing it could go like:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;data result ;&lt;/P&gt;&lt;P&gt;&amp;nbsp; if _n_=1 then&amp;nbsp; do;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; declare hash h(dataset:'matrix', multidata:'y');&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; h.definekey('lo_date');&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; h.definedata(ALL:'yes');&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; h.definedone();&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; set transaction;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; attrib int_rate format=percent. informat=percent. length=4 ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; call missing(lo_amount,int_rate); &lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; lo_date=effective_date;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; do rc=h.find() by 0 while (rc=0 &amp;amp; lo_amount &amp;lt;= balance);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rc=h.find_next();&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; if (rc = 0 ) then rc=h.find_prev() ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; /* put _all_ ; */ &lt;/P&gt;&lt;P&gt;run;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;As it are percentages (formatted) note that the precision is not decimal exact. &lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 04 Sep 2014 06:42:10 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185431#M35188</guid>
      <dc:creator>jakarman</dc:creator>
      <dc:date>2014-09-04T06:42:10Z</dc:date>
    </item>
    <item>
      <title>Re: Lookup Values from a Rate Matrix Table</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185432#M35189</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Jaap.&lt;/P&gt;&lt;P&gt;Unfortunately I am constrained using 9.1.3, hence no multi data option.&lt;/P&gt;&lt;P&gt;Is there a work around for this?&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 04 Sep 2014 11:37:44 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185432#M35189</guid>
      <dc:creator>Scott_Mitchell</dc:creator>
      <dc:date>2014-09-04T11:37:44Z</dc:date>
    </item>
    <item>
      <title>Re: Lookup Values from a Rate Matrix Table</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185433#M35190</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;The multidata is new at 9.2. &lt;/P&gt;&lt;P&gt;9.1.3 is already very old (2008), grrr why is lcm of SAS that bad as there is no license cost constraint. Yes it is a personal frustration.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I think that drops the hash approach. We are still having:&lt;/P&gt;&lt;P&gt;- a format usage I am thinking on:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; The date delivering a format name,,, the delivered format apply on the balance value&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; How many recodes (formats) do you have/expect&amp;nbsp;&amp;nbsp; (asked this before) &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; This is quite a unique but simple approach inputn usage. &lt;A class="active_link" href="http://support.sas.com/documentation/cdl/en/lefunctionsref/67398/HTML/default/viewer.htm#n1xdirhugd30qcn1szvchqcss3wv.htm" title="http://support.sas.com/documentation/cdl/en/lefunctionsref/67398/HTML/default/viewer.htm#n1xdirhugd30qcn1szvchqcss3wv.htm"&gt;SAS(R) 9.4 Functions and CALL Routines: Reference, Third Edition&lt;/A&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The code for this goes like:&lt;/P&gt;&lt;P&gt;/* ----------------------- */&lt;BR /&gt;proc format;&lt;BR /&gt; value recode_dt (default=16 max=32)&lt;BR /&gt; '01jan2014'd - '01feb2014'd = "rcd_1v." &lt;BR /&gt; '01feb2014'd - '01mar2014'd = "rcd_2v."&lt;BR /&gt;&amp;nbsp; other= "dummy" ;&lt;BR /&gt; invalue dummy &lt;BR /&gt;&amp;nbsp; other=. ; /* undefined recode */&amp;nbsp;&amp;nbsp; &lt;BR /&gt; invalue rcd_1v&lt;BR /&gt;&amp;nbsp; 0-&amp;lt;1000 = 0.00&amp;nbsp;&amp;nbsp; &lt;BR /&gt;&amp;nbsp; 1000-&amp;lt;10000 = 0.05&lt;BR /&gt;&amp;nbsp; 10000-&amp;lt;100000 = 0.10 &lt;BR /&gt;&amp;nbsp; 100000-High&amp;nbsp;&amp;nbsp; = 0.15 &lt;BR /&gt;&amp;nbsp; other=. ; /* undefined recode */&lt;BR /&gt; invalue rcd_2v&lt;BR /&gt;&amp;nbsp; 0-&amp;lt;1000 = 0.05&amp;nbsp;&amp;nbsp; &lt;BR /&gt;&amp;nbsp; 1000-&amp;lt;10000 = 0.1&lt;BR /&gt;&amp;nbsp; 10000-&amp;lt;100000 = 0.15 &lt;BR /&gt;&amp;nbsp; 100000-High&amp;nbsp;&amp;nbsp; = 0.20 &lt;BR /&gt;&amp;nbsp; other=. ; /* undefined recode */&lt;BR /&gt;run;&lt;/P&gt;&lt;P&gt;data result ;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; set transaction;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; attrib int_rate format=percent. length=4&amp;nbsp;&amp;nbsp; int_recod length=$8 ;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; int_recod=put(effective_date,recode_dt.);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; int_rate=inputn(put(balance,12.), int_recod) ; &lt;BR /&gt;run;&lt;/P&gt;&lt;P&gt;&lt;BR /&gt; &lt;/P&gt;&lt;P&gt;- a balanced merge on the data using a datastep.&amp;nbsp;&amp;nbsp; &lt;BR /&gt;&amp;nbsp; The assumption is sorted sas datasets&lt;/P&gt;&lt;P&gt;Need a sample ??&amp;nbsp; (there are more ways merge by, point usage)&lt;BR /&gt;SASfile usage to get the dataset into memory&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;SQL is probably slow as it does a full join and than selecting what is needed. your 100mb is blown up first. (Cartesian)&amp;nbsp; &lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;BR /&gt; &lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 04 Sep 2014 13:03:09 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185433#M35190</guid>
      <dc:creator>jakarman</dc:creator>
      <dc:date>2014-09-04T13:03:09Z</dc:date>
    </item>
    <item>
      <title>Re: Lookup Values from a Rate Matrix Table</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185434#M35191</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;HOHO, you must be kidding me . and let me know the feedback.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;PRE&gt;data Matrix_Table ;
input Lo_Date : ddmmyy10.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Lo_Amount&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Int_Rate : percent8.;
format Lo_Date ddmmyy10.;
cards;
1/01/2014&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0%
1/01/2014&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1000&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;5%
1/01/2014&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;10000&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;10%
1/01/2014&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;100000&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;15%
1/02/2014&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;5%
1/02/2014&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1000&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;10%
1/02/2014&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;10000&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;15%
1/02/2014&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;100000&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;20%
;
run;
data Transaction_Table ;
input Effective_Date : ddmmyy10.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Balance&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;;
format Effective_Date ddmmyy10.;
cards;
15/01/2014&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;11000
15/01/2014&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1000
15/01/2014&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;15000
15/01/2014&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;110000
15/01/2014&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;900
15/01/2014&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;100
15/01/2014&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;6000
15/01/2014&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;100001
15/01/2014&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;99999
15/02/2014&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;11000
15/02/2014&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1000
15/02/2014&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;15000
15/02/2014&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;110000
15/02/2014&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;900
15/02/2014&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;100
15/02/2014&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;6000
15/02/2014&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;100001
15/02/2014&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;99999
;
run;

data temp;
 set Matrix_table(rename=(Lo_Date=Effective_Date Lo_Amount=Balance) in=ina) Transaction_Table(in=inb);
 by Effective_Date&amp;nbsp; ;
 in2=inb;
 if ina=1 and ina ne lag(ina) then group+1;
run;
proc sort data=temp;by group balance; run;
data want(drop=in2 group Int_Rate);
 set temp;
 by group;
 retain rate;
 if first.group then call missing(rate);
 if not missing(Int_Rate) then rate=Int_Rate;
 if in2;
run;
&lt;/PRE&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Xia Keshan&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Message was edited by: xia keshan&amp;nbsp; &#xD;
Sorry, Fixed a problem.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 04 Sep 2014 15:11:45 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185434#M35191</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2014-09-04T15:11:45Z</dc:date>
    </item>
    <item>
      <title>Re: Lookup Values from a Rate Matrix Table</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185435#M35192</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Xia, no not kidding you. By the way I assumed the first dataset is missing those 5s for the same dates having a different recoding classification of the balance variable.&lt;/P&gt;&lt;P&gt;The line balance method is an optimized solution in 3g languages. You did a similar one but needed an additional resort for getting the wanted record. Thx&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 04 Sep 2014 15:48:29 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185435#M35192</guid>
      <dc:creator>jakarman</dc:creator>
      <dc:date>2014-09-04T15:48:29Z</dc:date>
    </item>
    <item>
      <title>Re: Lookup Values from a Rate Matrix Table</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185436#M35193</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Jaap,&lt;/P&gt;&lt;P&gt;I can't understand you . What is 3g language and why I need &lt;SPAN style="font-family: 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif; background-color: #ffffff;"&gt;an additional resort for getting the wanted record ?&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif; background-color: #ffffff;"&gt;I think I get the output OP desired .Don't you think so ?&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Xia Keshan&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 05 Sep 2014 13:19:19 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185436#M35193</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2014-09-05T13:19:19Z</dc:date>
    </item>
    <item>
      <title>Re: Lookup Values from a Rate Matrix Table</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185437#M35194</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Xia we are usually just seeing a small part of the OP's problem. &lt;BR /&gt;He has got a question to solve dis some steps he is knowing assuming they are the way to go. At the moment he gets blocked there is just some small part of the original question told. I try to get to that original question. In this case it looks to be there are several translations done by time. The first step The OP did was creating that matrix table. Of course I can be wrong, it is guess.&amp;nbsp; That is why I got on those format recoding way. &lt;BR /&gt;As example for his processing I am seeing he tried to used two dates as reference. Within the first one he missed the '5 to join those date's as exact match.&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/P&gt;&lt;P&gt;3G languages that are Cobol Fortran C Java&amp;nbsp; and a lot more. The difference with SAS is that auto-increment or record approach and much more like that.&amp;nbsp; &lt;A href="http://en.wikipedia.org/wiki/Fourth-generation_programming_language" title="http://en.wikipedia.org/wiki/Fourth-generation_programming_language"&gt;Fourth-generation programming language - Wikipedia, the free encyclopedia&lt;/A&gt;. With a 3GL there is much more need to be aware on how to do IO processing.&amp;nbsp; &lt;BR /&gt;The &lt;A href="http://www.isqa.unomaha.edu/haworth/isqa3300/fs006.htm" title="http://www.isqa.unomaha.edu/haworth/isqa3300/fs006.htm"&gt;Balance Line Algorithm&lt;/A&gt; is a standard known approach for fast efficient processing.&amp;nbsp; Asking for optimizing data processing problems that fit those conditions I would go for that kind.&amp;nbsp; The data set merge by (or set by) approach with SAS is one that is very alike balance line algorithm.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Did you help OP possible, we do not really know how is proceeding. When the turnaround time for him is acceptable and the coding is understandable maintainable, I guess that are the accept criteria, he should be happy.&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR /&gt; &lt;BR /&gt;&amp;nbsp; &lt;BR /&gt; &lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 05 Sep 2014 13:47:19 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185437#M35194</guid>
      <dc:creator>jakarman</dc:creator>
      <dc:date>2014-09-05T13:47:19Z</dc:date>
    </item>
    <item>
      <title>Re: Lookup Values from a Rate Matrix Table</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185438#M35195</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi,&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Try this, may be helpful in reducing execution time using sql.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;proc sql;&lt;/P&gt;&lt;P&gt;select Effective_Date,balance,Int_Rate from Transaction_Table, Matrix_Table&lt;/P&gt;&lt;P&gt;where month(Effective_Date) = month(lo_date)&lt;/P&gt;&lt;P&gt;and lo_amount&amp;lt;=balance&lt;/P&gt;&lt;P&gt;group by Effective_Date,balance&lt;/P&gt;&lt;P&gt;having Int_Rate=max(Int_Rate);&lt;/P&gt;&lt;P&gt;quit;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 05 Sep 2014 14:36:44 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185438#M35195</guid>
      <dc:creator>stat_sas</dc:creator>
      <dc:date>2014-09-05T14:36:44Z</dc:date>
    </item>
    <item>
      <title>Re: Lookup Values from a Rate Matrix Table</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185439#M35196</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;WOW, Jaap. &lt;/P&gt;&lt;P&gt;You are impressing me . Learn a lot from you.About DIS , I truly have no idea about it since you never touch it before .As I told you before , now I am focusing on statistical theory .&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Best&lt;/P&gt;&lt;P&gt;Xia Keshan&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 05 Sep 2014 14:44:38 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185439#M35196</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2014-09-05T14:44:38Z</dc:date>
    </item>
    <item>
      <title>Re: Lookup Values from a Rate Matrix Table</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185440#M35197</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Thank you all for your help and insights.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;In my initial question I simplified the issue considerably in an effort to engage more people.&amp;nbsp; In doing so I may have over simplified and caused greater confusion.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The bigger story is as follows:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Basically I have 4 variables by which I need to merge.&amp;nbsp; 1 variable (table) must equal the value in the in the matrix table and the other 3 should be greater than or equal to the value in the matrix.&amp;nbsp; The below produces a simulated version of the datasets I am working with.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;DATA MATRIX;&lt;BR /&gt;FORMAT LO_DATE DATE9.;&lt;BR /&gt;INFILE DATALINES;&lt;BR /&gt;INPUT LO_AMOUNT;&lt;BR /&gt;DO MATRIXTABLE = 81,85,100;&lt;BR /&gt; DO LO_DATE = "01JAN1980"D TO "05SEP2014"D;&lt;BR /&gt;&amp;nbsp; DO LO_FREQ = 1,12,40,60;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; INTRATE = RANUNI(0);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; OUTPUT;&lt;BR /&gt;&amp;nbsp; END;&lt;BR /&gt; END;&lt;BR /&gt;END;&lt;BR /&gt;DATALINES;&lt;BR /&gt;0&lt;BR /&gt;1000&lt;BR /&gt;5000&lt;BR /&gt;;&lt;BR /&gt;RUN;&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;DATA HISTORYTRANS;&lt;BR /&gt;ARRAY VARS $20 VAR1-VAR40;&lt;BR /&gt;FORMAT EFFECTIVEDATE DATE9.;&lt;BR /&gt;DO TABLE = 81,85,100;&lt;BR /&gt; DO EFFECTIVEDATE = "01JAN1980"D TO "05SEP2014"D BY CEIL(RANUNI(0)*100);&lt;BR /&gt;&amp;nbsp; DO FREQ = 1 TO 60 BY CEIL(RANUNI(0)*60);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; DO AMOUNT = 100 TO 1000000 BY CEIL(RANUNI(0)*1000000);&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DO I = 1 TO 40;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; VARS{I} = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; END;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IF RANUNI(0) &amp;lt; .20 THEN OUTPUT;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; END;&lt;BR /&gt;&amp;nbsp; END;&lt;BR /&gt; END;&lt;BR /&gt;END;&lt;BR /&gt;RUN;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;In the methods suggested thus far I am concerned about the number of times I will have to access each table to either group and sort, or create mountains of formats.&amp;nbsp; As a result I ran with a HASH ITERATOR.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;DATA LOOKUP;&lt;BR /&gt;IF 0 THEN SET MATRIX;&lt;BR /&gt;IF _N_ = 1 THEN DO;&lt;BR /&gt; DECLARE HASH H(DATASET:"MATRIX",ORDERED:"D", HASHEXP:16);&lt;BR /&gt; DECLARE HITER HI("H");&lt;BR /&gt; H.DEFINEKEY("MATRIXTABLE","LO_DATE","LO_FREQ","LO_AMOUNT");&lt;BR /&gt; H.DEFINEDATA("MATRIXTABLE","LO_DATE","LO_FREQ","LO_AMOUNT","INTRATE");&lt;BR /&gt; H.DEFINEDONE();&lt;BR /&gt;END;&lt;/P&gt;&lt;P&gt;SET HISTORYTRANS;&lt;/P&gt;&lt;P&gt;RC = HI.FIRST();&lt;/P&gt;&lt;P&gt;DO WHILE (RC = 0 AND INT_RATE = .);&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IF MATRIXTABLE = TABLE THEN&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IF LO_DATE &amp;lt;= EFFECTIVEDATE THEN&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IF LO_FREQ &amp;lt;= FREQ THEN&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IF LO_AMOUNT &amp;lt;= AMOUNT THEN DO;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; INT_RATE = INTRATE;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LEAVE;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; END;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RC = HI.NEXT();&lt;BR /&gt;END;&lt;/P&gt;&lt;P&gt;RUN;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I have seen an improvement in my processing time, down from 1.5Hrs down to 1Hr (ensuring that the 2 datasets remained static at 456012 records - Matrix and 30000 records - HistoryTrans&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;), but I would like to improve this further.&amp;nbsp; Will the previous recommendations (@JAAP and @KSHARP ) work under the above conditions?&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Could I please seek your further assistance?&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Regards,&lt;/P&gt;&lt;P&gt;Scott&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Mon, 08 Sep 2014 06:34:26 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185440#M35197</guid>
      <dc:creator>Scott_Mitchell</dc:creator>
      <dc:date>2014-09-08T06:34:26Z</dc:date>
    </item>
    <item>
      <title>Re: Lookup Values from a Rate Matrix Table</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185441#M35198</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Scott,&lt;/P&gt;&lt;P&gt;Your question is getting into the same direction as this one. &lt;A _jive_internal="true" href="https://communities.sas.com/thread/60762"&gt;https://communities.sas.com/thread/60762&lt;/A&gt;. It is more about performance/tuning and seeking the best algorithm for that. The hash object is working better as SQL but not a very dramatic one. The classic line-balance (sorted data) is far better. Xia already posted one based on a merge by approach.&amp;nbsp; This one with a result at JDmarino-s data from 5hr to 1 minute was sufficient to stop improvements.&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/P&gt;&lt;P&gt;Will try with your sample data.&lt;BR /&gt;Just to be complete, any description of underlying hardware (no processors memory io-speed). SAS version? &lt;BR /&gt;Options as memsize bufsize aligniofiles?&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;(updated)&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;What I am seeing is:&lt;BR /&gt;- I was hoping on some standard tables in matrix. With this setting there are 100.000 of them. Could work (one catalog) not my first choice.&lt;/P&gt;&lt;P&gt;- creating that datasets wil last for 0.23 and (matrix 456012 obs) en 0.06 second(historytrans 15486)&amp;nbsp; IO is no issue as memory to get the matrix in is no issue.&lt;/P&gt;&lt;P&gt;&amp;nbsp; Sorting those datasets is rather quick. As you are checking on the highest amount vale I did a descending order for amount.&lt;BR /&gt;&amp;nbsp; The wanted checking for freq is not really clear for me, could be a wrong one.&lt;/P&gt;&lt;P&gt;- On my computer the hashing is not getting to work (resources UE).&amp;nbsp; &lt;BR /&gt;- Analyzing your testdata, matrix is not sorted on lo_amount.&amp;nbsp;&amp;nbsp; &lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The balance line algorithm can run with a point=&amp;nbsp; usage that is working similar to the hash next.&lt;/P&gt;&lt;P&gt;Added is a reset to the starting date after each found record. It is not to the beginning of the dataset.&lt;/P&gt;&lt;P&gt;Id did not do something on missings. Could be needed.&lt;BR /&gt;This one runs in 3 minutes&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;proc sort data=matrix&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ;by matrixtable lo_Date lo_freq descending lo_amount&amp;nbsp; ; run;&lt;BR /&gt;proc sort data=HISTORYTRANS&amp;nbsp; ;by table EffectiveDate freq descending amount&amp;nbsp; ; run;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt; /*&amp;nbsp; -- */ &lt;BR /&gt; %let dsid = %sysfunc(open(matrix));&lt;BR /&gt; %let mat_nobs =%sysfunc(attrn(&amp;amp;dsid,NOBS));&lt;BR /&gt; %let rc = %sysfunc(close(&amp;amp;dsid));&lt;BR /&gt; %put matrix has &amp;amp;mat_nobs ;&lt;/P&gt;&lt;P&gt; data lookup ;&lt;BR /&gt;&amp;nbsp; set historytrans nobs=hst_nobs ;&lt;BR /&gt;&amp;nbsp; Retain eventlk 1&amp;nbsp; ; &lt;BR /&gt;&amp;nbsp; check=1 ;&lt;/P&gt;&lt;P&gt;&amp;nbsp; do while (eventlk &amp;lt; &amp;amp;mat_nobs &amp;amp; check ) ;&amp;nbsp; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; set matrix (rename=(intrate=int_rate)) point=eventlk&amp;nbsp; end=endprc ;&amp;nbsp; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IF MATRIXTABLE = TABLE &amp;amp; LO_DATE = EFFECTIVEDATE &amp;amp; LO_FREQ &amp;gt; FREQ &amp;amp; LO_AMOUNT &amp;lt; AMOUNT THEN DO;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; check=0;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; END;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Else&amp;nbsp; eventlk=eventlk+1; &lt;BR /&gt;&amp;nbsp; end;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR /&gt;&amp;nbsp; output; &lt;BR /&gt;&amp;nbsp; do while ( LO_DATE &amp;gt;= EFFECTIVEDATE &amp;amp; eventlK &amp;gt; 1);&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; eventlk=eventlk-1; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set matrix (rename=(intrate=int_rate)) point=eventlk&amp;nbsp; end=endprc ;&amp;nbsp; &lt;BR /&gt;&amp;nbsp; end;&lt;BR /&gt; run;&amp;nbsp; &lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Mon, 08 Sep 2014 07:30:58 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185441#M35198</guid>
      <dc:creator>jakarman</dc:creator>
      <dc:date>2014-09-08T07:30:58Z</dc:date>
    </item>
    <item>
      <title>Re: Lookup Values from a Rate Matrix Table</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185442#M35199</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi,&lt;/P&gt;&lt;P&gt;below is a combination of ideas.&lt;/P&gt;&lt;P&gt;I am &lt;STRONG&gt;storing a FREQxAMOUNT matrix in a hash object&lt;/STRONG&gt;,&lt;STRONG&gt; and updating it&lt;/STRONG&gt; if new information is available. (Note: this technique works only, if your LO_FREQ and LO_AMOUNT values are always the same for every date, or if this info is missing for a specific date. In your input data you shoul alway have an INTRATE for a transaction on the same day or before! If this is not true, some additional coding is needed.)&lt;/P&gt;&lt;P&gt;I think it would also work &lt;EM&gt;without&lt;/EM&gt; a hash table, but I wanted to keep the idea of the hash table, since in that case the transactions should be sorted only by TABLE and EFFECTIVEDATE (not by&amp;nbsp; LO_FREQ and LO_AMOUNT). Even the TABLE variable could be included in the hash - this would enable pure "stream processing" (no need for sortinig), provided your data originally is sorted by date. (Often transactional data comes already sorted.)&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;proc sort data=MATRIX;&lt;/P&gt;&lt;P&gt;by MATRIXTABLE LO_DATE;&lt;/P&gt;&lt;P&gt;run;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;DATA LOOKUP();&lt;/P&gt;&lt;P&gt;IF _N_ = 1 THEN DO;&lt;/P&gt;&lt;P&gt;DECLARE HASH H(ORDERED:"D",HASHEXP:16);&lt;/P&gt;&lt;P&gt;H.DEFINEKEY("LO_FREQ","LO_AMOUNT");&lt;/P&gt;&lt;P&gt;H.DEFINEDATA("LO_FREQ","LO_AMOUNT","INTRATE");&lt;/P&gt;&lt;P&gt;H.DEFINEDONE();&lt;/P&gt;&lt;P&gt;DECLARE HITER HI("H");&lt;/P&gt;&lt;P&gt;END;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;SET MATRIX(in=inM rename=(MATRIXTABLE=TABLE LO_DATE=EFFECTIVEDATE)) HISTORYTRANS();&lt;/P&gt;&lt;P&gt;by TABLE EFFECTIVEDATE /*FREQ AMOUNT*/;&lt;/P&gt;&lt;P&gt;if inM then do;/*record from MATRIX*/&lt;/P&gt;&lt;P&gt;&amp;nbsp; rc=h.add();&lt;/P&gt;&lt;P&gt;&amp;nbsp; if rc then h.replace();&lt;/P&gt;&lt;P&gt;end;&lt;/P&gt;&lt;P&gt;else do;/*record from HISTORYTRANS*/&lt;/P&gt;&lt;P&gt;&amp;nbsp; RC = HI.FIRST();&lt;/P&gt;&lt;P&gt;&amp;nbsp; DO WHILE (RC = 0);&lt;/P&gt;&lt;P&gt;&amp;nbsp; IF LO_FREQ &amp;lt;= FREQ and LO_AMOUNT &amp;lt;= AMOUNT THEN DO;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; output;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LEAVE;&lt;/P&gt;&lt;P&gt;&amp;nbsp; END;&lt;/P&gt;&lt;P&gt;&amp;nbsp; RC = HI.NEXT();&lt;/P&gt;&lt;P&gt;&amp;nbsp; END;&lt;/P&gt;&lt;P&gt;end;&lt;/P&gt;&lt;P&gt;RUN;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Mon, 08 Sep 2014 11:17:52 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185442#M35199</guid>
      <dc:creator>gergely_batho</dc:creator>
      <dc:date>2014-09-08T11:17:52Z</dc:date>
    </item>
    <item>
      <title>Re: Lookup Values from a Rate Matrix Table</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185443#M35200</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;I think this one is a far way.&lt;/P&gt;&lt;P&gt;Using the balance line in reversed sorted order (descending)&lt;/P&gt;&lt;P&gt;Going back to previous starting point as of a date marker&lt;BR /&gt;High/low values as markers to prevent overruns in values.&lt;/P&gt;&lt;P&gt;The proc sort for matrix is not relevant other than seeing it. The ordering of the hash itself will work&lt;/P&gt;&lt;P&gt;When the logic is all right the run time of it is amazing fast. &lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;proc sort data=matrix&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ;by descending matrixtable descending lo_Date descending lo_freq descending lo_amount&amp;nbsp; ; run;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;proc sort data=HISTORYTRANS&amp;nbsp; ;by descending table descending EffectiveDate descending freq descending amount&amp;nbsp; ; run;&lt;/P&gt;&lt;P&gt;DATA LOOKUP2;&lt;BR /&gt; retain RC ; &lt;BR /&gt; SET HISTORYTRANS ; &lt;/P&gt;&lt;P&gt; IF _N_ = 1 THEN DO;&lt;BR /&gt;&amp;nbsp; DECLARE HASH H(DATASET:"MATRIX",ORDERED:"D", HASHEXP:16);&lt;BR /&gt;&amp;nbsp; DECLARE HITER HI("H");&lt;BR /&gt;&amp;nbsp; H.DEFINEKEY("MATRIXTABLE","LO_DATE","LO_FREQ","LO_AMOUNT");&lt;BR /&gt;&amp;nbsp; H.DEFINEDATA("MATRIXTABLE","LO_DATE","LO_FREQ","LO_AMOUNT","INTRATE");&lt;BR /&gt;&amp;nbsp; H.DEFINEDONE();&lt;BR /&gt;&amp;nbsp; Call missing(MATRIXTABLE,LO_DATE,LO_FREQ,LO_AMOUNT,INTRATE) ;&lt;BR /&gt;&amp;nbsp; /* add addtional stops for up/down without error getting there&amp;nbsp; */&lt;BR /&gt;&amp;nbsp; Matrixtable=-1&amp;nbsp; ;lo_date='01jan1800'd; Lo_Freq=0; lo_amount=-1; RC = H.ADD();&lt;BR /&gt;&amp;nbsp; Matrixtable=9999;lo_date='01jan2200'd; Lo_Freq=0; lo_amount=-1; RC = H.ADD();&lt;BR /&gt; END;&lt;BR /&gt; format LO_date date. ;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &lt;BR /&gt; IF _N_ = 1 THEN RC = HI.FIRST();&lt;BR /&gt; DO WHILE (RC = 0 AND INT_RATE = .);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; IF MATRIXTABLE = TABLE &amp;amp; LO_DATE = EFFECTIVEDATE&amp;nbsp;&amp;nbsp;&amp;nbsp; THEN DO;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Do While (&amp;nbsp; LO_FREQ &amp;gt; FREQ ) ;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RC = HI.NEXT();&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end ; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Do While (&amp;nbsp;&amp;nbsp; LO_AMOUNT &amp;gt; AMOUNT&amp;nbsp; &amp;amp; LO_DATE = EFFECTIVEDATE&amp;nbsp; ) ;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RC = HI.NEXT();&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end ; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; INT_RATE = INTRATE;&amp;nbsp; &lt;BR /&gt;&amp;nbsp; END;&amp;nbsp;&amp;nbsp; &lt;BR /&gt;&amp;nbsp; Else Do;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; RC = HI.NEXT();&lt;BR /&gt;&amp;nbsp; END;&amp;nbsp;&amp;nbsp; &lt;BR /&gt; END;&lt;BR /&gt; OUTPUT ;&lt;BR /&gt; DO WHILE (LO_DATE &amp;lt;= EFFECTIVEDATE &amp;amp; RC = 0 );&lt;BR /&gt;&amp;nbsp;&amp;nbsp; RC = HI.PREV();&amp;nbsp; /* get back to starting point of date - previous date */&lt;BR /&gt; end;&lt;BR /&gt; run;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Mon, 08 Sep 2014 20:51:58 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185443#M35200</guid>
      <dc:creator>jakarman</dc:creator>
      <dc:date>2014-09-08T20:51:58Z</dc:date>
    </item>
    <item>
      <title>Re: Lookup Values from a Rate Matrix Table</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185444#M35201</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Jaap,&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The HASH approach was outstanding and gets the results that I want in a majority of occasions and I have made a tweak or 2 where appropriate.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I have one problem in the original example I had a LO_AMOUNT which was equal to 0 when in reality the lowest LO_AMOUNT is actually 1 (I hadn't been able to see the actual data until now and had to make the assumption that the lowest value would be 0).&amp;nbsp; If I come across an AMOUNT of 0 then the result displayed is&amp;nbsp; Matrixtable=-1&amp;nbsp; ;lo_date='01jan1800'd; Lo_Freq=0; lo_amount=-1 as expected.&amp;nbsp; The problem then appears to stop the look up for subsequent observations.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I have made several changes to the code to counter this including reading the hash from the beginning again and creating an if condition which creates an INT_RATE of 0 without processing the DO WHILE loop, but I am unable to get the desired outcome.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;My code appears as follows:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;DATA MATRIX;&lt;BR /&gt;FORMAT LO_DATE DATE9.;&lt;BR /&gt;INFILE DATALINES;&lt;BR /&gt;INPUT LO_AMOUNT;&lt;BR /&gt;DO MATRIXTABLE = 81,85,100;&lt;BR /&gt;DO LO_DATE = "01JAN1980"D TO "05SEP2014"D;&lt;BR /&gt;&amp;nbsp; DO LO_FREQ = 1,12,40,60;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; INTRATE = RANUNI(0);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; OUTPUT;&lt;BR /&gt;&amp;nbsp; END;&lt;BR /&gt;END;&lt;BR /&gt;END;&lt;BR /&gt;DATALINES;&lt;BR /&gt;1&lt;BR /&gt;1000&lt;BR /&gt;5000&lt;BR /&gt;10000&lt;BR /&gt;100000&lt;BR /&gt;1000000&lt;BR /&gt;;&lt;BR /&gt;RUN;&lt;/P&gt;&lt;P&gt;PROC SORT DATA=MATRIX;&lt;BR /&gt; BY LO_DATE; &lt;BR /&gt;RUN;&lt;/P&gt;&lt;P&gt;/*Outputting only every second date grouping to synthesize missing LO_DATES */&lt;/P&gt;&lt;P&gt;DATA MATRIX;&lt;BR /&gt; SET MATRIX;&lt;BR /&gt; BY LO_DATE; &lt;BR /&gt; IF FIRST.LO_DATE THEN GROUP +1;&lt;BR /&gt; IF FLOOR(GROUP/2) = GROUP/2 THEN OUTPUT;;&lt;BR /&gt;RUN;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;DATA HISTORYTRANS;&lt;BR /&gt;ARRAY VARS $20 VAR1-VAR40;&lt;BR /&gt;FORMAT EFFECTIVEDATE DATE9.;&lt;BR /&gt;DO TABLE = 81,85,100;&lt;BR /&gt;DO EFFECTIVEDATE = "01JAN1980"D TO "05SEP2014"D BY CEIL(RANUNI(0)*100);&lt;BR /&gt;&amp;nbsp; DO FREQ = 1 TO 60 BY CEIL(RANUNI(0)*60);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; DO AMOUNT = 0 TO 1000000 BY CEIL(RANUNI(0)*1000000);&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DO I = 1 TO 40;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; VARS{I} = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; END;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IF RANUNI(0) &amp;lt; .20 THEN OUTPUT;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; END;&lt;BR /&gt;&amp;nbsp; END;&lt;BR /&gt;END;&lt;BR /&gt;END;&lt;BR /&gt;RUN;&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;proc sort data=matrix;&lt;BR /&gt;by descending matrixtable descending lo_Date descending lo_freq descending lo_amount; &lt;BR /&gt;run;&lt;/P&gt;&lt;P&gt; &lt;BR /&gt;proc sort data=HISTORYTRANS&amp;nbsp; ;by descending table descending EffectiveDate descending freq descending amount&amp;nbsp; ; run;&lt;/P&gt;&lt;P&gt;DATA LOOKUP2;&lt;BR /&gt;retain RC ; &lt;BR /&gt;SET HISTORYTRANS (WHERE = (EFFECTIVEDATE &amp;gt; "01JAN1980"D)); &lt;/P&gt;&lt;P&gt;IF _N_ = 1 THEN DO;&lt;BR /&gt;&amp;nbsp; DECLARE HASH H(DATASET:"MATRIX",ORDERED:"D", HASHEXP:16);&lt;BR /&gt;&amp;nbsp; DECLARE HITER HI("H");&lt;BR /&gt;&amp;nbsp; H.DEFINEKEY("MATRIXTABLE","LO_DATE","LO_FREQ","LO_AMOUNT");&lt;BR /&gt;&amp;nbsp; H.DEFINEDATA("MATRIXTABLE","LO_DATE","LO_FREQ","LO_AMOUNT","INTRATE");&lt;BR /&gt;&amp;nbsp; H.DEFINEDONE();&lt;BR /&gt;&amp;nbsp; Call missing(MATRIXTABLE,LO_DATE,LO_FREQ,LO_AMOUNT,INTRATE) ;&lt;BR /&gt;&amp;nbsp; /* add addtional stops for up/down without error getting there&amp;nbsp; */&lt;BR /&gt;&amp;nbsp; Matrixtable=-1&amp;nbsp; ;lo_date='01jan1800'd; Lo_Freq=0; lo_amount=-1; RC = H.ADD();&lt;BR /&gt;&amp;nbsp; Matrixtable=9999;lo_date='01jan2200'd; Lo_Freq=0; lo_amount=-1; RC = H.ADD();&lt;BR /&gt;END;&lt;BR /&gt;format LO_DATE date9. ;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &lt;BR /&gt;DO WHILE (RC = 0 AND INT_RATE = .);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; IF MATRIXTABLE = TABLE&amp;nbsp;&amp;nbsp; THEN DO;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Do While (LO_DATE &amp;gt; EFFECTIVEDATE ) ;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RC = HI.NEXT();&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end ; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Do While (LO_FREQ &amp;gt; FREQ ) ;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RC = HI.NEXT();&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end ; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Do While (LO_AMOUNT &amp;gt; AMOUNT) ;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RC = HI.NEXT();&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end ; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; INT_RATE = INTRATE;&amp;nbsp; &lt;BR /&gt;&amp;nbsp; END;&amp;nbsp;&amp;nbsp; &lt;BR /&gt;&amp;nbsp; Else Do;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; RC = HI.NEXT();&lt;BR /&gt;&amp;nbsp; END;&amp;nbsp;&amp;nbsp; &lt;BR /&gt;END;&lt;BR /&gt;OUTPUT ;&lt;BR /&gt;DO WHILE (LO_DATE &amp;lt;= EFFECTIVEDATE &amp;amp; RC = 0 );&lt;BR /&gt;&amp;nbsp;&amp;nbsp; RC = HI.PREV();&amp;nbsp; /* get back to starting point of date - previous date */&lt;BR /&gt;END;&lt;BR /&gt;run;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Thank you again for all your help.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Tue, 09 Sep 2014 07:00:42 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185444#M35201</guid>
      <dc:creator>Scott_Mitchell</dc:creator>
      <dc:date>2014-09-09T07:00:42Z</dc:date>
    </item>
    <item>
      <title>Re: Lookup Values from a Rate Matrix Table</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185445#M35202</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;What I did is adding&amp;nbsp; error conditions.&lt;BR /&gt;- not going byond the current date in the inner loops&amp;nbsp; &lt;BR /&gt;- keeping the previous conditions&amp;nbsp; (reversed logic) as condition.&lt;/P&gt;&lt;P&gt;- only assiging int_rate when still all conditions are met&lt;BR /&gt;- recovery when something goes beyond scope an error (restart from scratch)&lt;/P&gt;&lt;P&gt;- error dataset for missed condtions.&lt;/P&gt;&lt;P&gt;As my session UE can behave badly going beyond limitations saved those in a permanent type.&amp;nbsp; &lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The whole idea is based on keeping searching just within that current date.&lt;BR /&gt;Knowing the power of factors and the ! function.&lt;/P&gt;&lt;P&gt;Your testdata is still running in the order off seconds on my machine. What is the result on your side?. &lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;libname test "/folders/myfolders/test"; &lt;/P&gt;&lt;P&gt;DATA test.MATRIX;&lt;BR /&gt;FORMAT LO_DATE DATE9.;&lt;BR /&gt;INFILE DATALINES;&lt;BR /&gt;INPUT LO_AMOUNT;&lt;BR /&gt;DO MATRIXTABLE = 81,85,100;&lt;BR /&gt; DO LO_DATE = "01JAN1980"D TO "05SEP2014"D;&lt;BR /&gt;&amp;nbsp; DO LO_FREQ = 1,12,40,60;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; INTRATE = RANUNI(0);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; OUTPUT;&lt;BR /&gt;&amp;nbsp; END;&lt;BR /&gt; END;&lt;BR /&gt;END;&lt;BR /&gt;DATALINES;&lt;BR /&gt;0&lt;BR /&gt;1000&lt;BR /&gt;5000&lt;BR /&gt;10000&lt;BR /&gt;100000&lt;BR /&gt;1000000&lt;BR /&gt;;&lt;BR /&gt;RUN;&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;DATA test.HISTORYTRANS (drop=i) ;&lt;BR /&gt;ARRAY VARS $20 VAR1-VAR40;&lt;BR /&gt;FORMAT EFFECTIVEDATE DATE9.;&lt;BR /&gt;DO TABLE = 81,85,100;&lt;BR /&gt; DO EFFECTIVEDATE = "01JAN1980"D TO "05SEP2014"D BY CEIL(RANUNI(0)*100);&lt;BR /&gt;&amp;nbsp; DO FREQ = 1 TO 60 BY CEIL(RANUNI(0)*60);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; DO AMOUNT = 100 TO 1000000 BY CEIL(RANUNI(0)*1000000);&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DO I = 1 TO 40;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; VARS{I} = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; END;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IF RANUNI(0) &amp;lt; .20 THEN OUTPUT;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; END;&lt;BR /&gt;&amp;nbsp; END;&lt;BR /&gt; END;&lt;BR /&gt;END;&lt;BR /&gt;RUN;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt; /*&amp;nbsp; -- */ &lt;BR /&gt;proc sort data=test.matrix&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ;by descending matrixtable descending lo_Date descending lo_freq descending lo_amount&amp;nbsp; ; run;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;proc sort data=test.HISTORYTRANS&amp;nbsp; ;by descending table descending EffectiveDate descending freq descending amount&amp;nbsp; ; run;&lt;/P&gt;&lt;P&gt;DATA test.Lookup test.lookup_err;&lt;BR /&gt; retain RC ; &lt;BR /&gt; SET test.HISTORYTRANS ; &lt;/P&gt;&lt;P&gt; IF _N_ = 1 THEN DO;&lt;BR /&gt;&amp;nbsp; DECLARE HASH H(DATASET:"test.MATRIX",ORDERED:"D", HASHEXP:16);&lt;BR /&gt;&amp;nbsp; DECLARE HITER HI("H");&lt;BR /&gt;&amp;nbsp; H.DEFINEKEY("MATRIXTABLE","LO_DATE","LO_FREQ","LO_AMOUNT");&lt;BR /&gt;&amp;nbsp; H.DEFINEDATA("MATRIXTABLE","LO_DATE","LO_FREQ","LO_AMOUNT","INTRATE");&lt;BR /&gt;&amp;nbsp; H.DEFINEDONE();&lt;BR /&gt;&amp;nbsp; Call missing(MATRIXTABLE,LO_DATE,LO_FREQ,LO_AMOUNT,INTRATE) ;&lt;BR /&gt;&amp;nbsp; /* add addtional stops for up/down without error getting there&amp;nbsp; */&lt;BR /&gt;&amp;nbsp; Matrixtable=-1&amp;nbsp; ;lo_date='01jan1800'd; Lo_Freq=0; lo_amount=-1; RC = H.ADD();&lt;BR /&gt;&amp;nbsp; Matrixtable=9999;lo_date='01jan2200'd; Lo_Freq=0; lo_amount=-1; RC = H.ADD();&lt;BR /&gt; END;&lt;BR /&gt; format LO_date date. ;&lt;BR /&gt; &lt;BR /&gt; IF (_N_ = 1 | RC not = 0&amp;nbsp; ) THEN RC = HI.FIRST();&lt;BR /&gt; DO WHILE (RC = 0 AND INT_RATE = .);&lt;BR /&gt;&amp;nbsp;&amp;nbsp; IF MATRIXTABLE = TABLE &amp;amp; LO_DATE = EFFECTIVEDATE&amp;nbsp;&amp;nbsp;&amp;nbsp; THEN DO;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Do While (&amp;nbsp; RC=0 &amp;amp; LO_FREQ &amp;gt; FREQ&amp;nbsp; &amp;amp; LO_DATE = EFFECTIVEDATE ) ;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RC = HI.NEXT();&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end ; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Do While (&amp;nbsp; RC=0&amp;nbsp; &amp;amp; LO_AMOUNT &amp;gt; AMOUNT&amp;nbsp; &amp;amp; LO_DATE = EFFECTIVEDATE&amp;nbsp; &amp;amp; LO_FREQ &amp;lt;=&amp;nbsp; Freq) ;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RC = HI.NEXT();&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end ; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ( RC = 0 &amp;amp; MATRIXTABLE = TABLE &amp;amp; LO_DATE = EFFECTIVEDATE &amp;amp; LO_FREQ &amp;lt;=&amp;nbsp; Freq &amp;amp; LO_AMOUNT &amp;lt;= AMOUNT ) then INT_RATE = INTRATE;&amp;nbsp; &lt;BR /&gt;&amp;nbsp; END;&amp;nbsp;&amp;nbsp; &lt;BR /&gt;&amp;nbsp; Else Do;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; RC = HI.NEXT();&lt;BR /&gt;&amp;nbsp; END;&amp;nbsp;&amp;nbsp; &lt;BR /&gt; END;&lt;BR /&gt; If (LO_Date = Effectivedate) then OUTPUT test.lookup ;&lt;BR /&gt; else output test.lookup_err;&lt;/P&gt;&lt;P&gt; IF ( RC not = 0 | LO_date &amp;lt; '01feb1800'd&amp;nbsp; ) THEN Do; &lt;BR /&gt;&amp;nbsp; put "reset search: " _N_ RC lo_date ;&amp;nbsp; &lt;BR /&gt;&amp;nbsp; RC = HI.FIRST();&lt;BR /&gt; end; &lt;BR /&gt; else DO WHILE (LO_DATE &amp;lt;= EFFECTIVEDATE &amp;amp; RC = 0 );&lt;BR /&gt;&amp;nbsp;&amp;nbsp; RC = HI.PREV();&amp;nbsp; /* get back to starting point of date - previous date */&lt;BR /&gt; end;&lt;/P&gt;&lt;P&gt; run;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Tue, 09 Sep 2014 09:03:54 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185445#M35202</guid>
      <dc:creator>jakarman</dc:creator>
      <dc:date>2014-09-09T09:03:54Z</dc:date>
    </item>
    <item>
      <title>Re: Lookup Values from a Rate Matrix Table</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185446#M35203</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;A newer hash approach is made. The Lo_date varies from 7305 to 19971.&lt;/P&gt;&lt;P&gt;Three temporary arrays are used to hold the values of matrixtable,&lt;/P&gt;&lt;P&gt;Lo_freq, and Lo_amount. &lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The variables from HISTORYTRANS are scanned with the values of arrays&lt;/P&gt;&lt;P&gt;to determine the first starting values for lookups. The index of the&lt;/P&gt;&lt;P&gt;each array for starting values is used in the subsequent do-loops and the index&lt;/P&gt;&lt;P&gt;is decremented if there is no hit. When there is a hit the output data set is &lt;/P&gt;&lt;P&gt;written and the do-loop is skipped to read the next record.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;In case the number of values in the temporary arrays are very large, a binary&lt;/P&gt;&lt;P&gt;search can be used to reduce the search time.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;This approach avoids the run-time for sorting the data sets.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;DATA MATRIX;&lt;/P&gt;&lt;P&gt;FORMAT LO_DATE DATE9.;&lt;/P&gt;&lt;P&gt;INFILE DATALINES;&lt;/P&gt;&lt;P&gt;INPUT LO_AMOUNT;&lt;/P&gt;&lt;P&gt;DO MATRIXTABLE = 81,85,100;&lt;/P&gt;&lt;P&gt;DO LO_DATE = "01JAN1980"D TO "05SEP2014"D;&lt;/P&gt;&lt;P&gt;&amp;nbsp; DO LO_FREQ = 1,12,40,60;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; INTRATE = RANUNI(0);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; OUTPUT;&lt;/P&gt;&lt;P&gt;&amp;nbsp; END;&lt;/P&gt;&lt;P&gt;END;&lt;/P&gt;&lt;P&gt;END;&lt;/P&gt;&lt;P&gt;DATALINES;&lt;/P&gt;&lt;P&gt;1&lt;/P&gt;&lt;P&gt;1000&lt;/P&gt;&lt;P&gt;5000&lt;/P&gt;&lt;P&gt;10000&lt;/P&gt;&lt;P&gt;100000&lt;/P&gt;&lt;P&gt;1000000&lt;/P&gt;&lt;P&gt;;&lt;/P&gt;&lt;P&gt;RUN;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;DATA HISTORYTRANS (drop=i) ;&lt;/P&gt;&lt;P&gt;*ARRAY VARS $20 VAR1-VAR40;&lt;/P&gt;&lt;P&gt;FORMAT EFFECTIVEDATE DATE9.;&lt;/P&gt;&lt;P&gt;DO TABLE = 81,85,100;&lt;/P&gt;&lt;P&gt;DO EFFECTIVEDATE = "01JAN1980"D TO "05SEP2014"D BY CEIL(RANUNI(0)*100);&lt;/P&gt;&lt;P&gt;&amp;nbsp; DO FREQ = 1 TO 60 BY CEIL(RANUNI(0)*60);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; DO AMOUNT = 100 TO 1000000 BY CEIL(RANUNI(0)*1000000);&lt;/P&gt;&lt;P&gt;/*&amp;nbsp;&amp;nbsp;&amp;nbsp; DO I = 1 TO 40;*/&lt;/P&gt;&lt;P&gt;/*&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; VARS{I} = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";*/&lt;/P&gt;&lt;P&gt;/*&amp;nbsp;&amp;nbsp;&amp;nbsp; END;*/&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IF RANUNI(0) &amp;lt; .20 THEN OUTPUT;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; END;&lt;/P&gt;&lt;P&gt;&amp;nbsp; END;&lt;/P&gt;&lt;P&gt;END;&lt;/P&gt;&lt;P&gt;END;&lt;/P&gt;&lt;P&gt;RUN;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;data need;&lt;/P&gt;&lt;P&gt;array t[3] _temporary_ (81, 85, 100);&lt;/P&gt;&lt;P&gt;array f[4] _temporary_ (1,12,40,60);&lt;/P&gt;&lt;P&gt;array a[6] _temporary_ (1, 1000, 5000, 10000, 100000, 1000000);&lt;/P&gt;&lt;P&gt;format matrixtable table lo_date effectivedate lo_freq freq lo_amount amount ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; if _n_ = 1 then do;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; retain max_date 19971 ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if 0 then set matrix;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; declare hash h(dataset:'matrix', ordered:'Y', hashexp:16);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; h.definekey('matrixtable','Lo_date','Lo_freq','Lo_amount');&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; h.definedata('intrate');&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; h.definedone();&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; set historytrans;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; do i = dim(t) to 1 by -1;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if t&lt;I&gt; &amp;lt;= table then do; m_table = i; leave; end;&lt;/I&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; Lo_date = ifN(effectivedate &amp;gt; max_date, max_date, effectivedate);&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; do i = dim(f) to 1 by -1 ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if f&lt;I&gt; &amp;lt;= freq then do; m_freq = i; leave; end;&lt;/I&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; do i = dim(a) to 1 by -1;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if a&lt;I&gt; &amp;lt;= amount then do; m_amount = i; leave; end;&lt;/I&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; rc = 0;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; do matrixtable = t[m_table] to t[1] by -1 while(rc = 0);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; do Lo_date = Lo_date to 7305 by -1 while(rc = 0);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; do Lo_freq = f[m_freq] to f[1] by -1 while(rc = 0);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; do Lo_amount = a[m_amount] to a[1] by -1 while(rc = 0);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rc = h.find();&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if rc = 0 then do; rc = 1; output; end;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;keep matrixtable table lo_date effectivedate lo_freq freq lo_amount amount ;&lt;/P&gt;&lt;P&gt;run;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Wed, 10 Sep 2014 14:48:43 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185446#M35203</guid>
      <dc:creator>KachiM</dc:creator>
      <dc:date>2014-09-10T14:48:43Z</dc:date>
    </item>
    <item>
      <title>Re: Lookup Values from a Rate Matrix Table</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185447#M35204</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;In my Post I missed to place the most important variable which is sought.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Add Variable, INTRATE, into 2 statements as:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;format matrixtable table lo_date effectivedate lo_freq freq lo_amount amount intrate;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;keep matrixtable table lo_date effectivedate lo_freq freq lo_amount amount intrate;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 11 Sep 2014 04:49:16 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185447#M35204</guid>
      <dc:creator>KachiM</dc:creator>
      <dc:date>2014-09-11T04:49:16Z</dc:date>
    </item>
    <item>
      <title>Re: Lookup Values from a Rate Matrix Table</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185448#M35205</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi All, maybe there’s a place here for a little (self)marketing. &lt;img id="smileyhappy" class="emoticon emoticon-smileyhappy" src="https://communities.sas.com/i/smilies/16x16_smiley-happy.png" alt="Smiley Happy" title="Smiley Happy" /&gt;&lt;/P&gt;&lt;P&gt;This problem involves looking up values in a table. The difficulty is, that there are no exact keys, instead we have intervals in the lookup table.&lt;/P&gt;&lt;P&gt;Most of the solutions use a hash table, and traverse it using &lt;STRONG&gt;many&lt;/STRONG&gt;&lt;EM&gt; hiter.next(), hiter.prev()&lt;/EM&gt; or &lt;EM&gt;hash.find()&lt;/EM&gt; method calls.&lt;/P&gt;&lt;P&gt;If you think that &lt;STRONG&gt;one&lt;/STRONG&gt; &lt;STRONG&gt;simple&lt;/STRONG&gt; method call that supports a &lt;STRONG&gt;direct "find greater than"&lt;/STRONG&gt; would be useful in a future SAS release, please vote here: &lt;A _jive_internal="true" href="https://communities.sas.com/ideas/1613"&gt;https://communities.sas.com/ideas/1613&lt;/A&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-size: 10pt; line-height: 1.5em;"&gt;By the way, I like Muthia’s method of handling many “non-exact” keys.&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-size: 10pt; line-height: 1.5em;"&gt;Thanks.&lt;BR /&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 11 Sep 2014 08:35:43 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185448#M35205</guid>
      <dc:creator>gergely_batho</dc:creator>
      <dc:date>2014-09-11T08:35:43Z</dc:date>
    </item>
    <item>
      <title>Re: Lookup Values from a Rate Matrix Table</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185449#M35206</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Gergely I updated you idea.&amp;nbsp; Tabel lookups are an everlasting topic for coding issues.&lt;/P&gt;&lt;P&gt;a/ SQL (full join),&lt;/P&gt;&lt;P&gt;b/ Formats,&lt;/P&gt;&lt;P&gt;c/ point=,&lt;/P&gt;&lt;P&gt;d/ hash and of&lt;/P&gt;&lt;P&gt;e/ course arrays (retained)&lt;/P&gt;&lt;P&gt;All of them behave different. There are many trying to compare them when they seem to be equal. More interesting is when they are offering different&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;This is a nice case study.&amp;nbsp; To get it more theoretical leaving the example as an example&amp;nbsp; &lt;/P&gt;&lt;P&gt;- matrix fixed values ,&amp;nbsp; test=eq &lt;/P&gt;&lt;P&gt;- dates&amp;nbsp; interval&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ,&amp;nbsp;&amp;nbsp; test=le&amp;nbsp; &lt;/P&gt;&lt;P&gt;- freq&amp;nbsp;&amp;nbsp;&amp;nbsp; interval&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ,&amp;nbsp;&amp;nbsp; test=ge&lt;/P&gt;&lt;P&gt;- amount variable&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ,&amp;nbsp;&amp;nbsp; test=le &lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Yes I know Chris:&lt;/P&gt;&lt;P&gt;- The matrix is defined as some fixed values but not how many of them there are. IT is an equal condition.&lt;/P&gt;&lt;P&gt;- has defined those dates as being all, This is also the approach to solve it by avoiding it and go for eq condition.&lt;/P&gt;&lt;P&gt;- The freq interval can be variable not having the same number and the same values for all dates&lt;/P&gt;&lt;P&gt;The amount variable is one leading to a new values dependent on one fixed and two variable intervals.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;ad a/ A SQL full join suffers from the Cartesian product&lt;/P&gt;&lt;P&gt;ad b/ Defining formats is possible with one variable interval (date) not with two (freq)&lt;/P&gt;&lt;P&gt;ad c/ Is workable needing a predefined order in the lookup dataset for manual search (no indexing possible in the combination)&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Ordering the base dataset also makes an algoritme possible that minimizes IO/Cpu.&amp;nbsp; &lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; The descending order can be used with sorting to optimize the positioning.&amp;nbsp; &lt;/P&gt;&lt;P&gt;ad d/ The hashing looks the same c/ but lacks either sorting order when working sequential or not having a find_ee.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; In this case we had luck that a descending order for all keys was a logical fit.&lt;BR /&gt;ad e/ Working with a arrays will need a full load of all lookups like the hash at the start or like the formats as namings.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; The variability can be problematic when not knowing the number of matrixtables or one of the other intervals as max sizings in advance&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 11 Sep 2014 10:47:55 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Lookup-Values-from-a-Rate-Matrix-Table/m-p/185449#M35206</guid>
      <dc:creator>jakarman</dc:creator>
      <dc:date>2014-09-11T10:47:55Z</dc:date>
    </item>
  </channel>
</rss>

