<?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: Merge loans data set with daily  data sets in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Merge-loans-data-set-with-daily-data-sets/m-p/823720#M325278</link>
    <description>Honestly ,I hate hash table. Is there another way?</description>
    <pubDate>Sun, 17 Jul 2022 14:42:51 GMT</pubDate>
    <dc:creator>Ronein</dc:creator>
    <dc:date>2022-07-17T14:42:51Z</dc:date>
    <item>
      <title>Merge loans data set with daily  data sets</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Merge-loans-data-set-with-daily-data-sets/m-p/823677#M325248</link>
      <description>Hello&lt;BR /&gt;It is a general question.&lt;BR /&gt;I have a data set ("Have data set")with loans taken by customers in last 2 years since July 2020 till now.( This table for example has 1 million rows)and fields in data set are:&lt;BR /&gt;Customer_Id, date ,amount, interest.&lt;BR /&gt;&lt;BR /&gt;There are daily data sets with information&lt;BR /&gt;of total obligation that each customer has to the bank.It includes following fields: Customer _Id, date, obligation.&lt;BR /&gt;The daily data sets are publisher every business day so in last 2 years there will be around 520 data sets ( because around 260 business days per year ).Each daily data set contains around 2 million rows.&lt;BR /&gt;Please note that the daily data sets are csv files so also need to import them into sas data sets in order to work with them.&lt;BR /&gt;The problem  that I cannot import all of the csv files in one step because  too much memory. &lt;BR /&gt;&lt;BR /&gt;For each row in the loans dats set("Have data set") I want to add information of obligation before loan and obligation after loan.It should be done in following way:&lt;BR /&gt;For obligation before:&lt;BR /&gt;Obligation one business day before date of loan and if not exists then 2 days before.&lt;BR /&gt;For obligation after:&lt;BR /&gt;Obligation in same date of loan.&lt;BR /&gt;&lt;BR /&gt;There is another data set that contains only one field called date and these are the list of business dates .&lt;BR /&gt;&lt;BR /&gt;My question:&lt;BR /&gt;What is the most efficient way to merge the "Have data set" with the daily data sets?&lt;BR /&gt;Option1-&lt;BR /&gt;I thought about using proc append to append all daily data sets and then merge it with "Have data set" but I think that it is too many rows ( 3 million×520)?&lt;BR /&gt;&lt;BR /&gt;Option2-&lt;BR /&gt;Merge the "Have data aet" with each daily data set so there will have 520 new columns with obligation_YYMMDD .&lt;BR /&gt;Then need to keep only the relevant 2&lt;BR /&gt;fields and rename them to obligation _before and obligation _after.&lt;BR /&gt;&lt;BR /&gt;Option3-&lt;BR /&gt;Splitting "Have data set" into multiple data sets by date of loans and then merge each loan data set with the relevant daily data set and then after merging need to append the resulted data sets.&lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;What is the best technique to merge the tables to get the desired data set?</description>
      <pubDate>Sun, 17 Jul 2022 05:28:46 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Merge-loans-data-set-with-daily-data-sets/m-p/823677#M325248</guid>
      <dc:creator>Ronein</dc:creator>
      <dc:date>2022-07-17T05:28:46Z</dc:date>
    </item>
    <item>
      <title>Re: Merge loans data set with daily  data sets</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Merge-loans-data-set-with-daily-data-sets/m-p/823683#M325254</link>
      <description>&lt;P&gt;I am not sure why&amp;nbsp; you are saying this: "The problem that I cannot import all of the csv files in one step because too much memory. "&lt;/P&gt;
&lt;P&gt;Unless you have restrictions on disk space memory shouldn't be an issue and a data step can read multiple files at one time. I am also a bit concerned with your use of "import" that you might have been considering proc import to read these. That many files would almost certainly result is differences between data sets that cause problems combining data. If you have a proper description of the files then writing a data step to read them is not difficult.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;There also shouldn't really be an issue with "I thought about using proc append to append all daily data sets and then merge it with "Have data set" but I think that it is too many rows ( 3 million×520)?"&amp;nbsp; If you read enough of this forum you will find questions with larger data sets. It just means that there will likely be some time elapse when using largish data sets.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Proliferation of data sets is seldom conducive to clean code, maintenance of code or even keeping track of where you are in a project.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I have a strong suspicion that your Option 2 with " there will have 520 new columns with obligation_YYMMDD " is a very sub-optimal approach. See all the discussions on this forum regarding "wide" vs "long". You would be writing a lot code trying to use 520 variables that gets cumbersome to maintain or understand.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Some dummy example data and the desired result might help.&lt;/P&gt;</description>
      <pubDate>Sun, 17 Jul 2022 08:44:46 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Merge-loans-data-set-with-daily-data-sets/m-p/823683#M325254</guid>
      <dc:creator>ballardw</dc:creator>
      <dc:date>2022-07-17T08:44:46Z</dc:date>
    </item>
    <item>
      <title>Re: Merge loans data set with daily  data sets</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Merge-loans-data-set-with-daily-data-sets/m-p/823685#M325256</link>
      <description>&lt;P&gt;The main issue I see is the concatenation of the 520 csv files into one dataset containing the daily data.&lt;/P&gt;
&lt;P&gt;What do the values in the daily datasets look like? Does the obligation change daily, or will it be constant over a span of days?&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;My approach would be to create one dataset out of the daily files, then merge it with the loan data, and write only one observation per loan once the necessary data is found.&lt;/P&gt;</description>
      <pubDate>Sun, 17 Jul 2022 10:24:53 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Merge-loans-data-set-with-daily-data-sets/m-p/823685#M325256</guid>
      <dc:creator>Kurt_Bremser</dc:creator>
      <dc:date>2022-07-17T10:24:53Z</dc:date>
    </item>
    <item>
      <title>Re: Merge loans data set with daily  data sets</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Merge-loans-data-set-with-daily-data-sets/m-p/823706#M325268</link>
      <description>All obligation daily data sets have same variables and same order of variables. &lt;BR /&gt;It is essential to work with all daily data sets because  obligation  can be changed daily .&lt;BR /&gt;The Question is how can I union 520 data sets with 2 million rows each...</description>
      <pubDate>Sun, 17 Jul 2022 13:17:43 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Merge-loans-data-set-with-daily-data-sets/m-p/823706#M325268</guid>
      <dc:creator>Ronein</dc:creator>
      <dc:date>2022-07-17T13:17:43Z</dc:date>
    </item>
    <item>
      <title>Re: Merge loans data set with daily  data sets</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Merge-loans-data-set-with-daily-data-sets/m-p/823707#M325269</link>
      <description>&lt;P&gt;From what you describe your loans table should easily fit into a hash table. If so then below code should work and perform reasonably well.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data loans;
  infile datalines dsd dlm=',' truncover;
  input customer_id $ loan_date:date9.;
  format loan_date date9.;
  datalines;
a,06Jun2022
b,07Jun2022
c,08Jun2022
;

data working_days;
  infile datalines dsd dlm=',' truncover;
  input seq_no wrkd_date:date9.;
  format wrkd_date date9.;
  datalines;
1,02Jun2022
2,03Jun2022
3,06Jun2022
4,07Jun2022
5,08Jun2022
;

/* this ds just for demo - in real use case infile statement in later data step */
data obligations;
  infile datalines dsd dlm=',' truncover;
  input customer_id $ obli_date:date9. obligation;
  format obli_date date9.;
  datalines;
a,03Jun2022,101
a,06Jun2022,101
b,02Jun2022,201
b,03Jun2022,201
b,07Jun2022,203
c,03Jun2022,301
c,06Jun2022,302
c,07Jun2022,303
c,08Jun2022,304
;

data prev_want(keep=customer_id loan_date obli_date obligation /* and the other columns from loans */);
  if _n_=1 then
    do;
      if 0 then set loans;
      dcl hash h_loans(dataset:'loans');
      h_loans.defineKey('customer_id');
      h_loans.defineData(all:'y');
      h_loans.defineDone();
      
      if 0 then set working_days;
      dcl hash h_wrkd_seq(dataset:'working_days');
      h_wrkd_seq.defineKey('wrkd_date');
      h_wrkd_seq.defineData('seq_no');
      h_wrkd_seq.defineDone();

      dcl hash h_wrkd(dataset:'working_days');
      h_wrkd.defineKey('seq_no');
      h_wrkd.defineData('wrkd_date');
      h_wrkd.defineDone();

    end;
  call missing(of _all_);

  /* this data set to make sample code work */
  set obligations;
  /* in real use case infile statement: assumed source file names sort by date */
/*  infile 'path to files/name*.csv';*/
/*  input &amp;lt;columns&amp;gt;;*/

  if h_loans.find()=0 then
    do;
      if 0&amp;lt;=loan_date-obli_date&amp;lt;=6 then 
        do;
          /* obligation for loan date */
          if loan_date=obli_date then 
            do;
              output;
              _rc=h_loans.remove();
            end;
          /* obligation one and two working days in the past */
          else
            do;
              /* get sequence number of working day for loan_date */
              _rc=h_wrkd_seq.find(key:loan_date);
              /* get working day one and two days in the past */
              do i=1 to 2;
                _rc=h_wrkd.find(key:seq_no-i);
                if wrkd_date=obli_date then 
                  do;
                    output;
                    leave;
                  end;
              end;
            end;
        end;
    end;
run;

/* select per customer_id the two most recent obli_dates */
proc sort data=prev_want;
  by customer_id descending obli_date;
run;
data want(drop=_:);
  set prev_want;
  by customer_id;
  if first.customer_id then _n=1;
  else _n+1;
  if _n&amp;lt;=2 then output;
run;

proc print data=want;
run;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;If your .csv all have a header column and/or don't follow a naming convention that makes them sort by date then some extensions to above proposed code will be necessary. If that's the case for you then ideally share sample .csv's that match above sample data.&lt;/P&gt;</description>
      <pubDate>Sun, 17 Jul 2022 15:15:52 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Merge-loans-data-set-with-daily-data-sets/m-p/823707#M325269</guid>
      <dc:creator>Patrick</dc:creator>
      <dc:date>2022-07-17T15:15:52Z</dc:date>
    </item>
    <item>
      <title>Re: Merge loans data set with daily  data sets</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Merge-loans-data-set-with-daily-data-sets/m-p/823709#M325270</link>
      <description>Sorry I didn't understand  this step.&lt;BR /&gt;There are 520 tables of obligation. &lt;BR /&gt;Which table should I read here??&lt;BR /&gt;&lt;BR /&gt;/* this ds just for demo - in real use case infile statement in later data step */&lt;BR /&gt;data obligations;&lt;BR /&gt;  infile datalines dsd dlm=',' truncover;&lt;BR /&gt;  input customer_id $ obli_date:date9. obligation;&lt;BR /&gt;  format obli_date date9.;&lt;BR /&gt;  datalines;&lt;BR /&gt;a,03Jun2022,101&lt;BR /&gt;a,06Jun2022,101&lt;BR /&gt;b,02Jun2022,201&lt;BR /&gt;b,03Jun2022,201&lt;BR /&gt;b,07Jun2022,203&lt;BR /&gt;c,03Jun2022,301&lt;BR /&gt;c,06Jun2022,302&lt;BR /&gt;c,07Jun2022,303&lt;BR /&gt;c,08Jun2022,304&lt;BR /&gt;;</description>
      <pubDate>Sun, 17 Jul 2022 13:34:08 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Merge-loans-data-set-with-daily-data-sets/m-p/823709#M325270</guid>
      <dc:creator>Ronein</dc:creator>
      <dc:date>2022-07-17T13:34:08Z</dc:date>
    </item>
    <item>
      <title>Re: Merge loans data set with daily  data sets</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Merge-loans-data-set-with-daily-data-sets/m-p/823712#M325272</link>
      <description>&lt;P&gt;You can use a * wildcard in the infile statement for SAS to read all the matching .csv in sequence.&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Patrick_0-1658065188746.png" style="width: 564px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/73371i08A4F29F5F53F526/image-dimensions/564x54?v=v2" width="564" height="54" role="button" title="Patrick_0-1658065188746.png" alt="Patrick_0-1658065188746.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;IF your .csv files follow a naming convention that sorts them by date - like: &amp;lt;name&amp;gt;_YYYYMMDD.csv - AND there is no header column in the files then things will work as proposed.&lt;/P&gt;
&lt;P&gt;If the files don't sort by date or there is a header column then please post (attach) a representative sample. The proposed code will only require a few tweaks to make it work in such a case.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Sun, 17 Jul 2022 13:43:55 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Merge-loans-data-set-with-daily-data-sets/m-p/823712#M325272</guid>
      <dc:creator>Patrick</dc:creator>
      <dc:date>2022-07-17T13:43:55Z</dc:date>
    </item>
    <item>
      <title>Re: Merge loans data set with daily  data sets</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Merge-loans-data-set-with-daily-data-sets/m-p/823713#M325273</link>
      <description>So as I understand  after read the obligation files I will have a data set which will contain more than 1 billion rows???</description>
      <pubDate>Sun, 17 Jul 2022 14:01:37 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Merge-loans-data-set-with-daily-data-sets/m-p/823713#M325273</guid>
      <dc:creator>Ronein</dc:creator>
      <dc:date>2022-07-17T14:01:37Z</dc:date>
    </item>
    <item>
      <title>Re: Merge loans data set with daily  data sets</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Merge-loans-data-set-with-daily-data-sets/m-p/823715#M325275</link>
      <description>&lt;BLOCKQUOTE&gt;&lt;HR /&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/159549"&gt;@Ronein&lt;/a&gt;&amp;nbsp;wrote:&lt;BR /&gt;So as I understand after read the obligation files I will have a data set which will contain more than 1 billion rows???&lt;HR /&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;No, not at all. Data step&amp;nbsp;&lt;EM&gt;data prev_want&lt;/EM&gt;&amp;nbsp;reads all the .csv's in sequence but only outputs "matching" records. If your loans table has a million rows then you get at most 3 million rows in output table &lt;EM&gt;prev_want.&lt;BR /&gt;&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;Because we process the .csv sequentially from oldest to newest AND based on your description there is a possibility that for loan_date minus one business day there might not be a matching record, the code needs to select matching rows for previous business days -1 and -2 ...and that's why some post processing is required. But that's then only on a table with not a lot of columns and max 3 million rows.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;To add to above: There won't be an obligations table. This table is only required for the sample code to be fully working because you didn't provide sample data including .csv's for multiple days. In your real code you won't create an obligations table but you will use the infile/input syntax provided in comment.&lt;/P&gt;</description>
      <pubDate>Sun, 17 Jul 2022 14:18:07 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Merge-loans-data-set-with-daily-data-sets/m-p/823715#M325275</guid>
      <dc:creator>Patrick</dc:creator>
      <dc:date>2022-07-17T14:18:07Z</dc:date>
    </item>
    <item>
      <title>Re: Merge loans data set with daily  data sets</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Merge-loans-data-set-with-daily-data-sets/m-p/823719#M325277</link>
      <description>Thank you. &lt;BR /&gt;Are you talking about regular concatenation of data sets using proc append when in the resulted data set will have 1 billion of rows? Is this number of rows possible?</description>
      <pubDate>Sun, 17 Jul 2022 14:41:34 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Merge-loans-data-set-with-daily-data-sets/m-p/823719#M325277</guid>
      <dc:creator>Ronein</dc:creator>
      <dc:date>2022-07-17T14:41:34Z</dc:date>
    </item>
    <item>
      <title>Re: Merge loans data set with daily  data sets</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Merge-loans-data-set-with-daily-data-sets/m-p/823720#M325278</link>
      <description>Honestly ,I hate hash table. Is there another way?</description>
      <pubDate>Sun, 17 Jul 2022 14:42:51 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Merge-loans-data-set-with-daily-data-sets/m-p/823720#M325278</guid>
      <dc:creator>Ronein</dc:creator>
      <dc:date>2022-07-17T14:42:51Z</dc:date>
    </item>
    <item>
      <title>Re: Merge loans data set with daily  data sets</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Merge-loans-data-set-with-daily-data-sets/m-p/823722#M325280</link>
      <description>&lt;BLOCKQUOTE&gt;&lt;HR /&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/159549"&gt;@Ronein&lt;/a&gt;&amp;nbsp;wrote:&lt;BR /&gt;Honestly ,I hate hash table. Is there another way?&lt;HR /&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Hash tables are a very powerful "tool" when it comes to creating performant code. With the data volumes you're dealing with performance is important. It's may-be worth for you to spend a bit of time to understand the code I've shared.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I won't spend time to propose a different approach only because you "hate hash tables" and I'm rather curious if someone else can propose something that will perform better without the use of hash tables (with only two columns one could create a format - but with a million customers that's certainly not better than a hash table).&lt;/P&gt;
&lt;P&gt;Any approach that first would need to create a SAS table with 520*2M rows is imho sub-optimal.&lt;/P&gt;</description>
      <pubDate>Sun, 17 Jul 2022 15:15:06 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Merge-loans-data-set-with-daily-data-sets/m-p/823722#M325280</guid>
      <dc:creator>Patrick</dc:creator>
      <dc:date>2022-07-17T15:15:06Z</dc:date>
    </item>
    <item>
      <title>Re: Merge loans data set with daily  data sets</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Merge-loans-data-set-with-daily-data-sets/m-p/823725#M325282</link>
      <description>&lt;P&gt;I was asking for constant obligation values because these would allow us to reduce the number of observations on import.&lt;/P&gt;
&lt;P&gt;Since they're not, the hash approach suggested by &lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/12447"&gt;@Patrick&lt;/a&gt;&amp;nbsp;is what I would also do.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Sun, 17 Jul 2022 15:11:30 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Merge-loans-data-set-with-daily-data-sets/m-p/823725#M325282</guid>
      <dc:creator>Kurt_Bremser</dc:creator>
      <dc:date>2022-07-17T15:11:30Z</dc:date>
    </item>
    <item>
      <title>Re: Merge loans data set with daily  data sets</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Merge-loans-data-set-with-daily-data-sets/m-p/823726#M325283</link>
      <description>I want yo ask again about this step  below&lt;BR /&gt;data obligations;&lt;BR /&gt;  infile datalines dsd dlm=',' truncover;&lt;BR /&gt;  input customer_id $ obli_date:date9. obligation;&lt;BR /&gt;  format obli_date date9.;&lt;BR /&gt;  datalines;&lt;BR /&gt;a,03Jun2022,101&lt;BR /&gt;a,06Jun2022,101&lt;BR /&gt;b,02Jun2022,201&lt;BR /&gt;b,03Jun2022,201&lt;BR /&gt;b,07Jun2022,203&lt;BR /&gt;c,03Jun2022,301&lt;BR /&gt;c,06Jun2022,302&lt;BR /&gt;c,07Jun2022,303&lt;BR /&gt;c,08Jun2022,304&lt;BR /&gt;;&lt;BR /&gt;&lt;BR /&gt;This is one step before create the has table.&lt;BR /&gt;How many rows will have in obligations data set  that was created here?&lt;BR /&gt;</description>
      <pubDate>Sun, 17 Jul 2022 15:37:52 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Merge-loans-data-set-with-daily-data-sets/m-p/823726#M325283</guid>
      <dc:creator>Ronein</dc:creator>
      <dc:date>2022-07-17T15:37:52Z</dc:date>
    </item>
    <item>
      <title>Re: Merge loans data set with daily  data sets</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Merge-loans-data-set-with-daily-data-sets/m-p/823729#M325285</link>
      <description>&lt;BLOCKQUOTE&gt;&lt;HR /&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/159549"&gt;@Ronein&lt;/a&gt;&amp;nbsp;wrote:&lt;BR /&gt;&lt;BR /&gt;How many rows will have in obligations data set that was created here?&lt;BR /&gt;&lt;BR /&gt;&lt;HR /&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;How many lines do you count in the DATALINES block?&lt;/P&gt;
&lt;P&gt;Or simply run the step in your SAS session and read the log.&lt;/P&gt;</description>
      <pubDate>Sun, 17 Jul 2022 16:30:12 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Merge-loans-data-set-with-daily-data-sets/m-p/823729#M325285</guid>
      <dc:creator>Kurt_Bremser</dc:creator>
      <dc:date>2022-07-17T16:30:12Z</dc:date>
    </item>
    <item>
      <title>Re: Merge loans data set with daily  data sets</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Merge-loans-data-set-with-daily-data-sets/m-p/823730#M325286</link>
      <description>9 lines&lt;BR /&gt;a,03Jun2022,101&lt;BR /&gt;a,06Jun2022,101&lt;BR /&gt;b,02Jun2022,201&lt;BR /&gt;b,03Jun2022,201&lt;BR /&gt;b,07Jun2022,203&lt;BR /&gt;c,03Jun2022,301&lt;BR /&gt;c,06Jun2022,302&lt;BR /&gt;c,07Jun2022,303&lt;BR /&gt;c,08Jun2022,304&lt;BR /&gt;&lt;BR /&gt;But in real life will have 520 lines???</description>
      <pubDate>Sun, 17 Jul 2022 16:35:03 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Merge-loans-data-set-with-daily-data-sets/m-p/823730#M325286</guid>
      <dc:creator>Ronein</dc:creator>
      <dc:date>2022-07-17T16:35:03Z</dc:date>
    </item>
    <item>
      <title>Re: Merge loans data set with daily  data sets</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Merge-loans-data-set-with-daily-data-sets/m-p/823731#M325287</link>
      <description>&lt;BLOCKQUOTE&gt;&lt;HR /&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/159549"&gt;@Ronein&lt;/a&gt;&amp;nbsp;wrote:&lt;BR /&gt;9 lines&lt;BR /&gt;a,03Jun2022,101&lt;BR /&gt;a,06Jun2022,101&lt;BR /&gt;b,02Jun2022,201&lt;BR /&gt;b,03Jun2022,201&lt;BR /&gt;b,07Jun2022,203&lt;BR /&gt;c,03Jun2022,301&lt;BR /&gt;c,06Jun2022,302&lt;BR /&gt;c,07Jun2022,303&lt;BR /&gt;c,08Jun2022,304&lt;BR /&gt;&lt;BR /&gt;But in real life will have 520 lines???&lt;HR /&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Why should it? It's just a "fake" dataset created to illustrate the function of the code presented in the post.&lt;/P&gt;</description>
      <pubDate>Sun, 17 Jul 2022 17:04:09 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Merge-loans-data-set-with-daily-data-sets/m-p/823731#M325287</guid>
      <dc:creator>Kurt_Bremser</dc:creator>
      <dc:date>2022-07-17T17:04:09Z</dc:date>
    </item>
    <item>
      <title>Re: Merge loans data set with daily  data sets</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Merge-loans-data-set-with-daily-data-sets/m-p/823738#M325292</link>
      <description>&lt;BLOCKQUOTE&gt;&lt;HR /&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/159549"&gt;@Ronein&lt;/a&gt;&amp;nbsp;wrote:&lt;BR /&gt;Honestly ,I hate hash table. Is there another way?&lt;HR /&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;HASH tables are not really that hard, they are use "foreign" to the normal SAS way of working.&lt;/P&gt;
&lt;P&gt;The advantage they have is that you can index into them by things like CUSTOMER_ID that is probably not a simple integer.&lt;/P&gt;
&lt;P&gt;In this case if the set of loans is small enough to fit in memory then you can find the obligations you are looking for with a single pass through the CSV file without having to create a giant SAS dataset.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The basic idea is to read a line from the CSV file and then use the HASH() object to decide if you need to keep that obligation amount.&amp;nbsp; When you get to the end of the data you can then write the HASH() object back to a dataset.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;You can use your list of business days in two ways.&amp;nbsp; One you can use it to help you figure out which date is the previous business day (or the previous previous business day).&amp;nbsp; Two you can use it to tell you which CSV files you need to read.&amp;nbsp; I assume you can figure out the name of the CSV file based on the date.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;So let's create some an example LOANS and BDAYS dataset and also a series of CSV files. Click the SPOILER tag to see the code.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI-SPOILER&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data loans;
  input customer_id $ date :yymmdd. amount;
  format date yymmdd10.;
datalines;
a 2022-06-06 100
b 2022-06-07 200
c 2022-06-08 300
;

data bdays;
  input date :yymmdd.;
  format date yymmdd10.;
datalines;
2022-06-02
2022-06-03
2022-06-06
2022-06-07
2022-06-08
;

data obligations;
  input customer_id $ date :yymmdd. obligation;
  format date yymmdd10.;
datalines;
b 2022-06-02 201
a 2022-06-03 101
b 2022-06-03 201
c 2022-06-03 301
a 2022-06-06 101
c 2022-06-06 302
b 2022-06-07 203
c 2022-06-07 303
c 2022-06-08 304
;

%let path=%sysfunc(pathname(work));
proc sort data=obligations;
  by date customer_id ;
run;

data _null_;
   set obligations end=eof;
   filename=cats("&amp;amp;path/balance_",put(date,yymmddn8.),'.csv');
   file csv filevar=filename dsd ;
   put customer_id date obligation ;
   if _n_=1 then call symputx('start',date);
   if eof then call symputx('end',date);
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;/LI-SPOILER&gt;
&lt;P&gt;Now let's see how to use those datasets and files to make what you want.&lt;/P&gt;
&lt;P&gt;First we need to know the path where to find the CSV files.&amp;nbsp; Also since this code is going to use a temporary array to figure out how to map from current business day to the next business day it will help to have a lower and upper bound on the range of dates.&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%let start=%sysfunc(mdy(02,06,2022));
%let end=%sysfunc(mdy(08,06,2022));
%let path=%sysfunc(pathname(work));&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Now here is the data step to read the obligations files and collect upto three obligation values per loan. The value on the loan date, on the previous business date and also the previous previous business date.&lt;/P&gt;
&lt;P&gt;First it will load the business days into a temporary array that map a date to the next business date.&lt;/P&gt;
&lt;P&gt;Second it will load the loan date into a hash that stores the customer, date, amount, and the three obligations.&lt;/P&gt;
&lt;P&gt;Third it will read in the list of dates and for each date read in the corresponding CSV file.&lt;/P&gt;
&lt;P&gt;For each record in the CSV file it checks if that customer+date matches a loan.&amp;nbsp; If so it stores the obligation in the hash.&lt;/P&gt;
&lt;P&gt;Then if checks if the next business is a loan date for this customer and if so it stores the obligation.&amp;nbsp; And repeats the look back (ahead) once more.&lt;/P&gt;
&lt;P&gt;Finally at the end it writes the hash to a dataset.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data _null_;
  if 0 then set bdays loans ;
  if _n_=1 then do;
    array nday [&amp;amp;start:&amp;amp;end] _temporary_;
    do while(not eof);
      set bdays end=eof;
      lag_date=lag(date);
      if not missing(lag_date) then nday[lag_date]=date;
    end;
    declare hash h(ordered:'yes');
    h.definekey('customer_id','date');
    h.definedata('customer_id','date','amount','owe1','owe2','owe3');
    h.definedone();
    do while(not eof1);
      set loans end=eof1;
      h.add();
    end;
  end;

  set bdays end=eof2;
  filename = cats("&amp;amp;path/balance_",put(date,yymmddn8.),'.csv');
  infile csv filevar=filename dsd truncover /*firstobs=2*/ end=eof3;
  do while(not eof3);
    input customer_id date :yymmdd. obligation ;
    date=date;
    if 0=h.find() then do; owe1=obligation; rc=h.replace(); end;
    date=nday[date];
    if not missing(date) then do;
      if 0=h.find() then do; owe2=obligation; rc=h.replace(); end;
      date=nday[date];
      if not missing(date) then do;
        if 0=h.find() then do; owe3=obligation; rc=h.replace(); end;
      end;
    end;
  end;

  if eof3 then rc=h.output(dataset:'loan_obligations');
run;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Results:&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Tom_0-1658082657752.png" style="width: 999px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/73376iA31D9E6751F34CD1/image-size/large?v=v2&amp;amp;px=999" role="button" title="Tom_0-1658082657752.png" alt="Tom_0-1658082657752.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Sun, 17 Jul 2022 18:31:10 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Merge-loans-data-set-with-daily-data-sets/m-p/823738#M325292</guid>
      <dc:creator>Tom</dc:creator>
      <dc:date>2022-07-17T18:31:10Z</dc:date>
    </item>
  </channel>
</rss>

