BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Cugel
Obsidian | Level 7


Hello who can help me with a loop function that runs through the days between a start date and an end date.

I am a beginner(newbee) in SAS proc SQL so please provide clear instructions

I work with a hospital admission table in which per patient a start date of the admission and the end date of the admission is stated.
Now I am looking for a loop function that runs through the day of the hospital admission.

The output is then used for further calculations and linking to other tables such as pain measurements per day.

Hopefully my question is clear and someone can help me. SAS DI version 4.903

 

Screen Shot 07-25-19 at 02.07 PM.JPG

1 ACCEPTED SOLUTION

Accepted Solutions
Cugel
Obsidian | Level 7

Hello Kurt

Your solution works like a train. Had to make a small adjustment in case the clinic start_admission_date and the clinic

end _admission_date fall on the same day. Patient stays in the hospital for only a few hours.

Maybe you have a smarter solution than my adjustment. Thank you for the suggested solution.

 

data want;
set have (rename=(end_date_admission=end_date));
if end_date = . then end_date = datetime();
day_date = datepart(start_date_admission);

if datepart(d_opn) ne datepart(end_date) then

do until (day_date >= datepart(end_date));
  end_date_admission = intnx('dtday',start_date_admission,1,'b');
  duration = intck('minute',start_date_admission,end_date_admission);
  output;
  day_date = day_date + 1;
  start_date_admission = end_date_admission;
end;

;
end_date_admission = end_date;
duration = intck('minute',start_date_admission,end_date_admission);
output;
drop end_date;
run;

View solution in original post

12 REPLIES 12
Kurt_Bremser
Super User

A simple do loop:

data want;
set have (rename=(end_date_admission=end_date));
if end_date = . then end_date = datetime();
day_date = datepart(start_date_admission);
do until (day_date >= datepart(end_date));
  end_date_admission = intnx('dtday',start_date_admission,1,'b');
  duration = intck('minute',,start_date_admission,end_date_admission);
  output;
  day_date = day_date + 1;
  start_date_admission = end_date_admission;
end;
end_date_admission = end_date;
duration = intck('minute',start_date_admission,end_date_admission);
output;
drop end_date;
run;

Untested, for lack of usable data.

 

Please post example data in a data step with datalines, so we can easily recreate your dataset(s) with a copy/paste and submit. Nobody here is keen on tediously typing data off a picture. Help us to help you.

Cugel
Obsidian | Level 7

Hello Kurt

Your solution works like a train. Had to make a small adjustment in case the clinic start_admission_date and the clinic

end _admission_date fall on the same day. Patient stays in the hospital for only a few hours.

Maybe you have a smarter solution than my adjustment. Thank you for the suggested solution.

 

data want;
set have (rename=(end_date_admission=end_date));
if end_date = . then end_date = datetime();
day_date = datepart(start_date_admission);

if datepart(d_opn) ne datepart(end_date) then

do until (day_date >= datepart(end_date));
  end_date_admission = intnx('dtday',start_date_admission,1,'b');
  duration = intck('minute',start_date_admission,end_date_admission);
  output;
  day_date = day_date + 1;
  start_date_admission = end_date_admission;
end;

;
end_date_admission = end_date;
duration = intck('minute',start_date_admission,end_date_admission);
output;
drop end_date;
run;

Kurt_Bremser
Super User

Given your variable names, the condition should be

if datepart(start_date_admission) ne datepart(end_date) then

Otherwise, it solves the problem of one-day stays very nicely.

Cugel
Obsidian | Level 7
Hello Kurt, thank you very much for your input.

However, the final solution is not yet clear.

I now have insight into the days within the hospitalization period.

But the next problem is that a patient may have been in multiple nursing units on one calendar day.

I will compile a dataset that makes that clear.

To be continued.
Cugel
Obsidian | Level 7

Hello Kurt,

 

Your proc sql procedure works well.

But I have an additional question.

The output of the procedure is written to an Oracle table, but now Oracle does not correctly process the format of the "day_date" field.

Is it possible to make the field "day_date" a datetime20. format?

 

Thanks in advance for your response.

Kurt_Bremser
Super User

To convert a date to a datetime value, do

day_date = dhms(day_date,0,0,0);
format day_date datetime20.;

or in SQL

dhms(day_date,0,0,0) format=datetime20. as day_date
Cugel
Obsidian | Level 7
Hello Kert,
Thanks the suggested solution works. I have not yet tested it in the proc sql procedure. The adjustment below gave the desired result.
[cid:image001.png@01D579F3.2DA30590]
Cugel
Obsidian | Level 7

Hello Kurt,

May I again appeal to you for your SAS knowledge.

In nursing, we use three daily rosters for the nurses.

Now we would like to split the length of stay on the ward per calendar day into the duration of stay per roster.

This is quite a puzzle since the length of stay can start in roster1 and end in roster2 or start in roster1 and also end in roster1 etc. etc..

Maybe you have a suggestion, idea or solution.

Thanks in advance for your response.

 

Roster1 23:30 until 07:30 (>23:30 <=07:30) (duration 8 hours --> 30 minutes until midnight and 450 minutes until start roster2) 

Roster2 07:30 until 15:30 (>07:30 <=15:30)  (duration 8 hours)

Roster3 15:30 until 23:30 (>15:30 <=23:30)  (duration 8 hours)

 

data_input

data_input.JPG

desired output

desirable_output.JPG

ballardw
Super User

Standard SQL does not have a Do loop construct.

LinusH
Tourmaline | Level 20

My take on this would be joining with a date/time dimension using a BETWEEN AND join criteria.

Thus avoiding using User Written code.

Data never sleeps
Cugel
Obsidian | Level 7

Hello Linus, As a learning newbee, I also looked at your proposed solution.

Unfortunately it is unclear to me how a join can make the intervening records visible between the start_admission_date and the end_admission_date. I have a dim_date table. Maybe you can explain the join statement.

 

 

INPUT FROM Oracle TABLE "ADMISSION"

PATIENT_IDADMISSION_IDSTART_DATE_ADMISSIONEND_DATE_ADMISSION
19955782369264015-07-2019 00:0118-07-2019 11:08
13787632369264215-07-2019 00:2515-07-2019 10:15
14384682369266115-07-2019 02:48.
16556502369266215-07-2019 05:43.
24735372369380115-07-2019 13:4018-07-2019 14:57
14335122369400315-07-2019 14:2322-07-2019 13:15

 

Records for July 2019 in the dim_date table.

SK_DIM_DATEDATE9DDMMYYD10DATE_CHAR
4364601JUL2019:00:00:0001-07-201901-jul-19
4364702JUL2019:00:00:0002-07-201902-jul-19
4364803JUL2019:00:00:0003-07-201903-jul-19
4364904JUL2019:00:00:0004-07-201904-jul-19
4365005JUL2019:00:00:0005-07-201905-jul-19
4365106JUL2019:00:00:0006-07-201906-jul-19
4365207JUL2019:00:00:0007-07-201907-jul-19
4365308JUL2019:00:00:0008-07-201908-jul-19
4365409JUL2019:00:00:0009-07-201909-jul-19
4365510JUL2019:00:00:0010-07-201910-jul-19
4365611JUL2019:00:00:0011-07-201911-jul-19
4365712JUL2019:00:00:0012-07-201912-jul-19
4365813JUL2019:00:00:0013-07-201913-jul-19
4365914JUL2019:00:00:0014-07-201914-jul-19
4366015JUL2019:00:00:0015-07-201915-jul-19
4366116JUL2019:00:00:0016-07-201916-jul-19
4366217JUL2019:00:00:0017-07-201917-jul-19
4366318JUL2019:00:00:0018-07-201918-jul-19
4366419JUL2019:00:00:0019-07-201919-jul-19
4366520JUL2019:00:00:0020-07-201920-jul-19
4366621JUL2019:00:00:0021-07-201921-jul-19
4366722JUL2019:00:00:0022-07-201922-jul-19
4366823JUL2019:00:00:0023-07-201923-jul-19
4366924JUL2019:00:00:0024-07-201924-jul-19
4367025JUL2019:00:00:0025-07-201925-jul-19
4367126JUL2019:00:00:0026-07-201926-jul-19
4367227JUL2019:00:00:0027-07-201927-jul-19
4367328JUL2019:00:00:0028-07-201928-jul-19
4367429JUL2019:00:00:0029-07-201929-jul-19
4367530JUL2019:00:00:0030-07-201930-jul-19
4367631JUL2019:00:00:0031-07-201931-jul-19
Kurt_Bremser
Super User
proc sql;
create table want as
select
  a.patient_id,
  a.admission_id,
  b.date9
from admission a, dim_date b
where b.date9 between a.start_date_admission and a.end_date_admission
;
quit;

This is the code you need to achieve with the point-and-click interface, if you don't want to use a user written transformation in DI Studio.

sas-innovate-white.png

Our biggest data and AI event of the year.

Don’t miss the livestream kicking off May 7. It’s free. It’s easy. And it’s the best seat in the house.

Join us virtually with our complimentary SAS Innovate Digital Pass. Watch live or on-demand in multiple languages, with translations available to help you get the most out of every session.

 

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.

SAS Training: Just a Click Away

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

Browse our catalog!

Discussion stats
  • 12 replies
  • 4506 views
  • 3 likes
  • 4 in conversation