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

I would like to transpose the following dataset so that I can calculate the time difference between the patients first and second hospitalization. How would I do that with duplicate identifiers?

 

This is how my dataset is presently formatted (and some patients may have more than two hospitalizations)

 

Patient NamePatient IDAdmission dateTest date
Pete Smith1231/2/202012/25/2019
Pete Smith1233/5/202012/25/2019
Sarah Jones4562/2/20201/25/2020
Sarah Jones4564/5/20201/25/2020
Mark Adams7894/7/20203/25/2020
Mark Adams7896/1/20203/25/2020

 

This is how I would like it to look

 

Patient NamePatient IDTest dateAdmission dateAdmission date
Pete Smith12312/25/20191/2/20203/5/2020
Sarah Jones4561/25/20202/2/20204/5/2020
Mark Adams7893/25/20204/7/20206/1/2020

Is transposing the best way to do this? Or would I have to merge?

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

You didn't show any code.  Just a listing.

 

First let's convert your original listing into an actual dataset so we have something to code with.

data have;
  input name & :$30. id admit :mmddyy. test :mmddyy.;
  format admit test yymmdd10.;
cards;
Pete Smith   123 1/2/2020 12/25/2019
Pete Smith   123 3/5/2020 12/25/2019
Sarah Jones  456 2/2/2020 1/25/2020
Sarah Jones  456 4/5/2020 1/25/2020
Mark Adams   789 4/7/2020 3/25/2020
Mark Adams   789 6/1/2020 3/25/2020
;

Since it is already sorted by ID we can skip the sorting and go straight to transposing it.

proc transpose data=have out=want prefix=admit;
  by id name test;
run;

Result:

Obs     id       name              test    _NAME_        admit1        admit2

 1     123    Pete Smith     2019-12-25    admit     2020-01-02    2020-03-05
 2     456    Sarah Jones    2020-01-25    admit     2020-02-02    2020-04-05
 3     789    Mark Adams     2020-03-25    admit     2020-04-07    2020-06-01

Now if you want to find the difference in DAYS between ADMIT1 and ADMIT2 you can use subtraction.  If you want it in some other date interval use INTCK() function.

data differenes;
  set want;
  days = admit2-admit1;
  months = intck('month',admit1,admit2,'cont');
run;

Result

Obs     id       name              test    _NAME_        admit1        admit2    days    months

 1     123    Pete Smith     2019-12-25    admit     2020-01-02    2020-03-05     63        2
 2     456    Sarah Jones    2020-01-25    admit     2020-02-02    2020-04-05     63        2
 3     789    Mark Adams     2020-03-25    admit     2020-04-07    2020-06-01     55        1

 

View solution in original post

6 REPLIES 6
Tom
Super User Tom
Super User

That data poses no problem for PROC TRANSPOSE.

proc transpose data=have out=want(drop=_name_) prefix=admitdate ;
  by patientid patientname testdate;
  var admitdate;
run;
cc15
Fluorite | Level 6

I tried the following code, but did not get the desired results, this is what I got:

Patient NamePatient IDName of former variableAdmission date1Test date
Pete Smith123Admission date1/2/202012/25/2019
Pete Smith123Admission date3/5/202012/25/2019
Sarah Jones456Admission date2/2/20201/25/2020
Sarah Jones456Admission date4/5/20201/25/2020
Mark Adams789Admission date4/7/20203/25/2020
Mark Adams789Admission date6/1/20203/25/2020
Tom
Super User Tom
Super User

You didn't show any code.  Just a listing.

 

First let's convert your original listing into an actual dataset so we have something to code with.

data have;
  input name & :$30. id admit :mmddyy. test :mmddyy.;
  format admit test yymmdd10.;
cards;
Pete Smith   123 1/2/2020 12/25/2019
Pete Smith   123 3/5/2020 12/25/2019
Sarah Jones  456 2/2/2020 1/25/2020
Sarah Jones  456 4/5/2020 1/25/2020
Mark Adams   789 4/7/2020 3/25/2020
Mark Adams   789 6/1/2020 3/25/2020
;

Since it is already sorted by ID we can skip the sorting and go straight to transposing it.

proc transpose data=have out=want prefix=admit;
  by id name test;
run;

Result:

Obs     id       name              test    _NAME_        admit1        admit2

 1     123    Pete Smith     2019-12-25    admit     2020-01-02    2020-03-05
 2     456    Sarah Jones    2020-01-25    admit     2020-02-02    2020-04-05
 3     789    Mark Adams     2020-03-25    admit     2020-04-07    2020-06-01

Now if you want to find the difference in DAYS between ADMIT1 and ADMIT2 you can use subtraction.  If you want it in some other date interval use INTCK() function.

data differenes;
  set want;
  days = admit2-admit1;
  months = intck('month',admit1,admit2,'cont');
run;

Result

Obs     id       name              test    _NAME_        admit1        admit2    days    months

 1     123    Pete Smith     2019-12-25    admit     2020-01-02    2020-03-05     63        2
 2     456    Sarah Jones    2020-01-25    admit     2020-02-02    2020-04-05     63        2
 3     789    Mark Adams     2020-03-25    admit     2020-04-07    2020-06-01     55        1

 

A_Kh
Lapis Lazuli | Level 10

Alternatively, without changing data structure, it is possible to calculate time difference (eg. how many days) using proc sql summary functions.
Eg:

data have;
infile cards dlm=',' truncover; 
length PatientName $20;
input PatientName $	PatientID $	Admissiondate:mmddyy10.	Testdate: mmddyy10.;
format Admissiondate	Testdate date11.; 
cards; 
Pete Smith,	123,	1/2/2020,	12/25/2019
Pete Smith,	123,	3/5/2020,	12/25/2019
Sarah Jones,	456,	2/2/2020,	1/25/2020
Sarah Jones,	456,	4/5/2020,	1/25/2020
Mark Adams,	789,	4/7/2020,	3/25/2020
Mark Adams,	789,	6/1/2020,	3/25/2020
; 

proc sql;
	create table want as
		select*, min(Admissiondate) as FirstAdmissionDate, max(Admissiondate) as LastAdmissionDate
			from have
		group by 1, 2, 4
	order by 2,3;
quit; 

Days= LastAdmissionDate - FirstAdmissionDate; 

Tom
Super User Tom
Super User

@cc15 wrote:

... so that I can calculate the time difference between the patients first and second hospitalization ...


No need to transpose to do that.

data want;
  set have;
  by patientid admitdate ;
  days = dif(admitdate);
  if first.patientid then do;
      admitdate1 = admitdate;
     retain admitdate1 ;
    format admitdate1 yymmdd10.;
      days=0;
  end;
  if last.patientid;
run;

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
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
  • 6 replies
  • 570 views
  • 2 likes
  • 4 in conversation