BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
David_Billa
Rhodochrosite | Level 12

May I know how can we simplify this step? Multiple IF blocks are confusing and also the retain statement. If we cant simplify this step, can someone explain this code in simple terms? I understand the SAS functions but I'm not getting the whole picture here.

 

DATA WORK.BASELINE;
       SET WORK.BASELINE_;
       BASSTRTM2 = INPUT(substr(BSSTRTM,1,2)||':'||substr(BSSTRTM,4,2)||':'||SUBSTR(BSSTRTM,7,2),TIME5.);
       BASFINTM2 = INPUT(substr(BASFINTM,1,2)||':'||substr(BASFINTM,4,2)||':'||SUBSTR(BASFINTM,7,2),TIME5.);
       
       BASSTRTDTTM = DHMS(BAS_STRT_DT,0,0,BASSTRTM2);
       BASFINDTTM = DHMS(BAS_FINISH_DT,0,0,BASFINTM2);
       POSTDTTM = DHMS(POSTNG_DT,0,0,0);
       
       BASEHRS = INTCK('HOURS',BASSTRTDTTM,BASFINDTTM,'continuous');
       IF BASEHRS < 1 THEN BASEHRS = 1;
       IF BAS_STRT_DT = POSTNG_DT THEN
       DO;
              IF DAYS_OF_PO = 1 THEN
                     DO;
                           INITIALHRS = BASEHRS;
                           NEWBASEHRS=INITIALHRS;
                           DAYHRS = INITIALHRS;
                     END;
              ELSE
                     DO;
                           INITIALHRS = INTCK('HOURS',BASSTRTDTTM,DHMS(bas_strt_dt,24,0,0),'CONTINUOUS');
                           DAYHRS = INTCK('HOURS',BASSTRTDTTM,DHMS(bas_strt_dt,24,0,0),'CONTINUOUS');
                           NEWBASEHRS=BASEHRS-INITIALHRS;
                     END;
       END;
       ELSE IF BAS_FINISH_DT = POSTNG_DT THEN  
              DO;
              DAYHRS = NEWBASEHRS;
              END;
       ELSE 
              DO;
              DAYHRS = 24;
              NEWBASEHRS=NEWBASEHRS-DAYHRS;
              END;
       RETAIN INITIALHRS;
       RETAIN NEWBASEHRS;
       RUN;

1 ACCEPTED SOLUTION

Accepted Solutions
mkeintz
PROC Star

A question: why use 

       ELSE IF BAS_FINISH_DT = POSTNG_DT THEN  
              DO;
              DAYHRS = NEWBASEHRS;
              END;

instead of

       ELSE IF BAS_FINISH_DT = POSTNG_DT THEN DAYHRS = NEWBASEHRS;

You apparently can't drop the RETAIN statements, because there are some conditions in which a new value for INITIALHRS or NEWBASEHRS will not be calculated, and you apparently want to carry forward the previous values instead of resetting them to missing..

 

 

Now, if you're really just trying to reduce lines of code, you could change

       IF BAS_STRT_DT = POSTNG_DT THEN
       DO;
              IF DAYS_OF_PO = 1 THEN
                     DO;
                           INITIALHRS = BASEHRS;
                           NEWBASEHRS=INITIALHRS;
                           DAYHRS = INITIALHRS;
                     END;
              ELSE
                     DO;
                           INITIALHRS = INTCK('HOURS',BASSTRTDTTM,DHMS(bas_strt_dt,24,0,0),'CONTINUOUS');
                           DAYHRS = INTCK('HOURS',BASSTRTDTTM,DHMS(bas_strt_dt,24,0,0),'CONTINUOUS');
                           NEWBASEHRS=BASEHRS-INITIALHRS;
                     END;
       END;

to

  IF BAS_STRT_DT = POSTNG_DT THEN DO;
    INITIALHRS= ifn(days_of_po=1,BASEHRS   ,INTCK('HOURS',BASSTRTDTTM,DHMS(bas_strt_dt,24,0,0),'CONTINUOUS'));
    DAYHRS    = ifn(days_of_po=1,INITIALHRS,INTCK('HOURS',BASSTRTDTTM,DHMS(bas_strt_dt,24,0,0),'CONTINUOUS'));
    NEWBASEHRS= ifn(days_of_po=1,INITIALHRS,BASEHRS-INITIALHRS);
  END;

But it would take a little longer to run.  I wouldn't recommend it.

 

Note: This comment was intended to be a response to the OP (@pink_poodle), but was erroneously issued as a reply to @David_Billa 

 

--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------

View solution in original post

6 REPLIES 6
ballardw
Super User

Example data. Source and expected result and possibly a description of the problem to really provide any meaningful difference in the code.

 

This stuff looks like it would like to read a time value that was written with something other than : as the original delimiter.

Without an example of the source value not much that can be suggested.

       BASSTRTM2 = INPUT(substr(BSSTRTM,1,2)||':'||substr(BSSTRTM,4,2)||':'||SUBSTR(BSSTRTM,7,2),TIME5.);
       BASFINTM2 = INPUT(substr(BASFINTM,1,2)||':'||substr(BASFINTM,4,2)||':'||SUBSTR(BASFINTM,7,2),TIME5.);

 

I don't see much way to address your "ifs". Your "multiple" are pretty much 2 at each point. So not much to reduce.

 

This code apparently is calculating some sort of offset from some date condition that is reset when one of the values reaches 1. The RETAIN means values available from the first reset are available until reset. Not much of any other way if you need those variables for calculations on the right side of the =.  I am not sure that the Initialhrs needs to be retained from the code I see but the Newbasehrs is used to set Dayhrs.

David_Billa
Rhodochrosite | Level 12
So not much can be simplified without seeing the data?
SASKiwi
PROC Star

It would help a lot if you could not only provide some sample input and output data, but also explain in plain English the process this DATA step is part of. Where is this data being sourced and what is it being used for? Not having any business context makes it even harder to figure out what it is doing.  

David_Billa
Rhodochrosite | Level 12
Well, can someone help me understand that ELSE IF block?
mkeintz
PROC Star

A question: why use 

       ELSE IF BAS_FINISH_DT = POSTNG_DT THEN  
              DO;
              DAYHRS = NEWBASEHRS;
              END;

instead of

       ELSE IF BAS_FINISH_DT = POSTNG_DT THEN DAYHRS = NEWBASEHRS;

You apparently can't drop the RETAIN statements, because there are some conditions in which a new value for INITIALHRS or NEWBASEHRS will not be calculated, and you apparently want to carry forward the previous values instead of resetting them to missing..

 

 

Now, if you're really just trying to reduce lines of code, you could change

       IF BAS_STRT_DT = POSTNG_DT THEN
       DO;
              IF DAYS_OF_PO = 1 THEN
                     DO;
                           INITIALHRS = BASEHRS;
                           NEWBASEHRS=INITIALHRS;
                           DAYHRS = INITIALHRS;
                     END;
              ELSE
                     DO;
                           INITIALHRS = INTCK('HOURS',BASSTRTDTTM,DHMS(bas_strt_dt,24,0,0),'CONTINUOUS');
                           DAYHRS = INTCK('HOURS',BASSTRTDTTM,DHMS(bas_strt_dt,24,0,0),'CONTINUOUS');
                           NEWBASEHRS=BASEHRS-INITIALHRS;
                     END;
       END;

to

  IF BAS_STRT_DT = POSTNG_DT THEN DO;
    INITIALHRS= ifn(days_of_po=1,BASEHRS   ,INTCK('HOURS',BASSTRTDTTM,DHMS(bas_strt_dt,24,0,0),'CONTINUOUS'));
    DAYHRS    = ifn(days_of_po=1,INITIALHRS,INTCK('HOURS',BASSTRTDTTM,DHMS(bas_strt_dt,24,0,0),'CONTINUOUS'));
    NEWBASEHRS= ifn(days_of_po=1,INITIALHRS,BASEHRS-INITIALHRS);
  END;

But it would take a little longer to run.  I wouldn't recommend it.

 

Note: This comment was intended to be a response to the OP (@pink_poodle), but was erroneously issued as a reply to @David_Billa 

 

--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------
pink_poodle
Barite | Level 11
This program accrues work hours? It takes the date stamps from the log for start and finish and checks if positive hours can be computed. It also checks date time when they were posted and how that compares to start and finish.

hackathon24-white-horiz.png

The 2025 SAS Hackathon Kicks Off on June 11!

Watch the live Hackathon Kickoff to get all the essential information about the SAS Hackathon—including how to join, how to participate, and expert tips for success.

YouTube LinkedIn

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 6 replies
  • 1250 views
  • 3 likes
  • 5 in conversation