BookmarkSubscribeRSS Feed
maroulator
Obsidian | Level 7

I have been working with the code below and it runs well. The basic idea is for macro COLLATERAL to keep being called by the OUTER macro (via a %do-%while loop); the loop in the OUTER macro terminates once the variable DIFFERENCE reaches zero (the variable DIFFERENCE can be found in the last lines of code of the macro COLLATERAL). What I need this code for is to determine the value of the %ADD_COLL variable in the OUTER macro that will make the variable DIFFERENCE in the macro COLLATERAL equal to (or very close to) zero. Notice that the variable DIFFERENCE flows from the OUTER macro into the COLLATERAL macro. My problem is this; from my experience, I know that variable     %ADD_COLL can assume values in the thousands and more often than not in the millions (i.e, 160,000,000 etc). This being the case, my loop runs for a very very long time, because I am currently incrementing the %ADD_COLL variable by 1 after each iteration. If I increment %ADD_COLL faster, however (say by 1,000,0000 at a time), I run into the risk of overshooting the correct value of %ADD_COLL oftentimes by too much and prematurely halting my loop in the macro OUTER. Is there a way to increment %ADD_COLL more quickly without, overshooting; I was thinking of somehow starting with a large increment for %ADD_COLL, adjusting the increment in the event of an overshoot and then incrementing %ADD_COLL by a new amount that will not lead to another overshot. I am open to all suggestions, however, along with the appropriate coding solution. Many thanks in advance; below is the code in question.

%global finish add_coll;

%macro collateral();

   

      data all_daily_fees2;

           set all_daily_fees;

           collateral2=collateral+&add_coll;

           add_coll=&add_coll;

           if newbal<0 then do;

                 if abs(newbal)>collateral2 then do;

                 newcollod2=collateral2;

                 newuncollod2=abs((collateral2+newbal));

                 end;

                 else do;

                 newcollod2=abs(newbal);

                 newuncollod2;

                 end;

             end;

             else do;

             newcollod2=0;

             newuncollod2=0;

             end;

      run;

      data all_daily_fees3;

             set all_daily_fees2;

                      if fee_cd='F' then do;

                             if bal<0 then daily_cr_net=0.0000124*(uncollod/1291);

                             else daily_cr_net=0;

                              if newbal<0 then newdaily_cr_net=0.0000124*(newuncollod2/1291);

                              else newdaily_cr_net=0;

                       end;

        run;

      proc sql;

          create table all_daily_fees4 as

          select aba, sum(daily_cr_net) as rmp_cr_net, sum(newdaily_cr_net) as newrmp_cr_net

          from all_daily_fees3;

          group by aba;

       quit;

     data rmp_fees;

         set all_daily_fees4;

              assessed_fees=max(0, rmp_cr_net-150);

             newassessed_fees=max(0,newrmp_cr_net-150);

             difference=newassessed_fees-assessed_fees;

             if difference<0 then call symputx('finish',0);

       run;

%mend collateral();

%macro outer();

      %let add_coll=0;

      %let finish=1;

      %do %while (&finish);

          %collateral();

         %let add_coll = %eval(&add_coll+1);

      %end;

%mend outer();

%outer();

           


3 REPLIES 3
Patrick
Opal | Level 21

First thing would be to strip down your code an reduce passes through data. You basically could do the whole thing in a single data _null_ step. For me to be motivated to put in the effort and strip your code you first must post code where you've got the business logic right and where the syntax is correct.

The code you've posted contains 2 syntax errors. So this can't be what you're succesfully running and it's now only about tweaking for performance.

maroulator
Obsidian | Level 7

What are the syntax errors?

Patrick
Opal | Level 21

Run the code you've posted and the log will tell you. Or even better: Look first at your code in a more recent SAS editor and ask yourself why there is stuff highlighted in red. Fix it, then run your code and if there are no more errors or warnings in the log check if the result is as expected. Once you're there post your code again and ask for performance tweaking. Please provide also a log so that we can see with what volumes we're dealing here.

Syntax error 1: What's the line "newuncollod2;" supossed to achieve?

                 newcollod2=abs(newbal);

                 newuncollod2;

                 end;

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 3 replies
  • 529 views
  • 0 likes
  • 2 in conversation