BookmarkSubscribeRSS Feed
mkeintz
PROC Star

@ssitharath0420

 

I asked why you have 355  (not 335). Your answer now raises another question.  You chose to ignore Dec 31,2016 because it's the 366th day of the year, thereby getting 334 total days for 1A.  Does that mean someone with coverage from Jan 1-Dec 30 has 1 day less than Jan 2-Dec 31? 

 

Anyhow, assuming that's what you mean, then this should work:

 

 

data want (drop=n j d first_n cutdate mindate overlap);

  /* Read all recs for a patid, to determine which rec has earliest SERV_DATE1 */
  do N=1 by 1 until (last.patid);
    set testing;
    by patid;
    if serv_date1<mindate or N=1 then first_N=N;
    mindate=min(mindate,serv_date1);
  end;

  cutdate="01jan2016"d + 365; /* Earliest day to NOT include */
  array sd {*} serv_date: ;
  array ds {*} days_supply: ;

  /* Reread all N recs for a patid, and calc coverage days*/
  do J=1 to N;
    set testing;
    days=0;

    length class $13;
    if  N=1 then class='MONO';
    else if J=first_n then class='First Therapy';
    else class='Add On';

    do d=1 to dim(sd) while (ds{d}^=.);
      if d>1 then overlap = max(0,sd{d-1}+ds{d-1}+1-sd{d});
      else overlap=0;
      days=days+min(cutdate-sd{d},ds{d})-overlap;
    end;
    output;
  end;
run;

 

 

If this is a solution to your original task, then it shows the value and time savings of a clearly stated problem accompanied by an input example and a correct output  example.

--------------------------
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

--------------------------
ssitharath0420
Quartz | Level 8
What about Patient Id 5. This person switch to a new therapy. Patio 5 took therapy A from 01/01/2016 to 04/01/2016 and switch to therapy B from 05/01/2016 to 12/01/2016.
mkeintz
PROC Star

This solution uses proc sort, which I usually like to avoid because the result file does not have the same record order as the source data (often unwanted) and sorting large files can be expensive.  However:

 


proc sort data=testing out=need;
  by patid serv_date1;
run;

data want (drop=d cutdate overlap end_date);
  set need;
  by patid;

  cutdate="01jan2016"d + 365; /* Earliest day to NOT include */
  array sd {*} serv_date: ;
  array ds {*} days_supply: ;

  days=0;
  do d=1 to dim(sd) while (ds{d}^=.);
    if d>1 then overlap = max(0,sd{d-1}+ds{d-1}+1-sd{d});
    else overlap=0;
    days = days + min(cutdate-sd{d},ds{d})-overlap;
  end;
  end_date = serv_date1 + days -1;

  length class $13; 
  class =ifc(serv_date1>lag(end_date),'SWITCH','ADD ON'); 
  if first.patid=1 and last.patid=1 then class='MONO'; 
  else if first.patid then class='First Therapy'; 
run;
--------------------------
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

--------------------------
ssitharath0420
Quartz | Level 8

Hi Mkeintz,

 

I tried to use your code but the days covered were not coming out to what I expected.

 

I developed this code below and it give me the correct days covered.  I also used your code to determine the class.  That was great!  I liked your code because it was short and simple but unfortunately it wasn't giving me the correct days covered.

 

data WORK.TESTING;
  infile datalines dsd truncover;
  input PATID:32. Therapy:$1. serv_date1:DATE9. serv_date2:DATE9. serv_date3:DATE9. serv_date4:DATE9. serv_date5:DATE9. days_supply1:32. days_supply2:32. days_supply3:32. days_supply4:32. days_supply5:32.;
datalines4;
1,A,11JAN2016,13APR2016,18JUL2016,28OCT2016,,90,90,90,90,
1,B,18JUN2016,22SEP2016,13DEC2016,28DEC2016,,90,90,30,30,
2,A,11JAN2016,18APR2016,14JUL2016,13OCT2016,,90,90,90,90,
2,B,11JAN2016,16APR2016,18JUL2016,13OCT2016,22NOV2016,90,90,90,90,90
3,A,02MAR2016,29AUG2016,05NOV2016,,,90,90,90,,
3,B,05FEB2016,28JUN2016,06SEP2016,02DEC2016,,90,90,90,90,
3,C,26MAR2016,27JUN2016,06SEP2016,29NOV2016,,90,90,90,90,
4,A,01JAN2016,01APR2016,13APR2016,31DEC2016,,90,90,90,30,
5,A,01JAN2016,01FEB2016,01MAR2016,01APR2016,,30,30,30,30,
5,B,01MAY2016,01JUN2016,01JUL2016,01AUG2016,,30,30,30,30,
;;;;

proc sort data=testing out=need;
  by patid serv_date1;
run;

data want;
set need;
format start_dt end_dt date9.;
start_dt=serv_date1;
end_dt=serv_date1+365;
run;

data want1 (keep=patid Therapy serv_date1 - serv_date5 days_supply1-days_supply5 dayscovered);
set want;
format adj_serv_date1- adj_serv_date5 date9.;
array adjfilldat(*)adj_serv_date1 - adj_serv_date5;
array daydummy(365) day1-day365;
array filldates(*) serv_date1 - serv_date5;
array days_supply(*) days_supply1-days_supply5;

/*adjust fill dates*/
do p = 1 to 5;
adjfilldat(p) = '01Jan2016'd;
adjfilldat(p)= filldates(p);
end;
drop p;
do u=2 to 5 while (adjfilldat(u) ne .);
if adjfilldat(u)<adjfilldat(u-1)+days_supply(u-1)
then adjfilldat(u)=adjfilldat(u-1)+days_supply(u-1);
end;
drop u;

start_dt_au = '01Jan2016'd;
dumm_start = start_dt-start_dt_au;

do ii=1 to 365; daydummy(ii)=0;end;
do ii=dumm_start to 365;
do i = 1 to dim(adjfilldat) while (adjfilldat(i) ne .);
if adjfilldat(i)<= start_dt_au + ii -1 <= adjfilldat(i)+days_supply(i)-1
then daydummy(ii)=1;
end;
end;
drop i ii;
dayscovered=sum(of day1 - day365);label dayscovered='Total Days Covered';
p_dayscovered=dayscovered/365;label p_dayscovered='Proportion of Days Covered';

run;

proc sort data=want1 out=want2;
  by patid serv_date1;
run;

data Final;
set want2;
by patid;

end_date = serv_date1 + dayscovered -1;
length class $13;
  class =ifc(serv_date1>lag(end_date),'SWITCH','ADD ON');
  if first.patid=1 and last.patid=1 then class='MONO';
  else if first.patid then class='First Therapy';
run;

 

Output

 

PATIDTherapyserv_date1serv_date2serv_date3serv_date4serv_date5days_supply1days_supply2days_supply3days_supply4days_supply5dayscoveredclass
1A1/11/20164/13/20167/18/201610/28/2016 90909090 334First Therapy
1B6/18/20169/22/201612/13/201612/28/2016 90903030 190ADD ON
2A1/11/20164/18/20167/14/201610/13/2016 90909090 347First Therapy
2B1/11/20164/16/20167/18/201610/13/201611/22/20169090909090346ADD ON
3B2/5/20166/28/20169/6/201612/2/2016 90909090 276First Therapy
3A3/2/20168/29/201611/5/2016  909090  214ADD ON
3C3/26/20166/27/20169/6/201611/29/2016 90909090 277ADD ON
4A1/1/20164/1/20164/13/201612/31/2016 90909030 270MONO
5A1/1/20162/1/20163/1/20164/1/2016 30303030 120First Therapy
5B5/1/20166/1/20167/1/20168/1/2016 30303030 120SWITCH

 

Thank you so much for your help!

ssitharath0420
Quartz | Level 8
What about Patient Id 5. This person switch to a new therapy. Patio 5 took therapy A from 01/01/2016 to 04/01/2016 and switch to therapy B from 05/01/2016 to 12/01/2016.
mkeintz
PROC Star
If therapy A ends on day X, and B begins the very next day, is that a switch? Or must there be uncovered days between the two therapies?
--------------------------
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

--------------------------
ssitharath0420
Quartz | Level 8
It can begin the next day as long as patient is no longer taking A.
ssitharath0420
Quartz | Level 8

Does that mean someone with coverage from Jan 1-Dec 30 has 1 day less than Jan 2-Dec 31?   No they should not.  If th patient filled on 12/31/2016, it should be included.

SAS Innovate 2025: Call for Content

Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!

Submit your idea!

What is Bayesian Analysis?

Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.

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
  • 22 replies
  • 1647 views
  • 0 likes
  • 4 in conversation