- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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;
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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
--------------------------
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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
--------------------------
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content