Hi @Cruise
Next try - Thise code handles diagnosis dates in coverage intervals as well as before/after/between intervals, so it replaces the code from yesterday. Example data is expanded to cover both.
There is a problem in your example data, where ID = 10 has elig_end8 = '31DEC', which is read as a missing value. Is it a typo in your example data, that doesn't occur in real life, or should invalid dates be handled somehow? And I guess that some patients have a current valid insurance coverage, so there is no "natural" elig_end. how is that expressed in data?
I ask these questions because the code I posted yesterday doesn't work if the last interval has a missing elig_end, and the diagnosis date is in that interval, and the same problem arises with the problem in your recent post, where the number of days between last elig_end and a diagnosis date after that can't be determined in case of missing elig_end.
I have coded a workaround, so a missing elig_end in the last interval as interpreted as "forever, so in that case a patient is coded as covered, i.e. cov0 = 1, if the diagnosis date is after elig_beg in the last interval.
In your previous post you wanted the actual insurance interval that covers a given patient id included in output, and I suppose you would also want the nearest insurance interval together with the number of days before/after, so I included that in the code.
DATA HAVE;
format id 8. DATE_DIAGNOSIS elig_beg1 elig_end1 elig_beg2 elig_end2 elig_beg3 elig_end3 elig_beg4 elig_end4 elig_beg5 elig_end5 elig_beg6 elig_end6 elig_beg7 elig_end7 elig_beg8 elig_end8 date9.;
informat DATE_DIAGNOSIS elig_beg1 elig_end1 elig_beg2 elig_end2 elig_beg3 elig_end3 elig_beg4 elig_end4 elig_beg5 elig_end5 elig_beg6 elig_end6 elig_beg7 elig_end7 elig_beg8 elig_end8 date9.;
input ID DATE_DIAGNOSIS elig_beg1 elig_end1 elig_beg2 elig_end2 elig_beg3 elig_end3 elig_beg4 elig_end4 elig_beg5 elig_end5 elig_beg6 elig_end6 elig_beg7 elig_end7 elig_beg8 elig_end8;
cards;
1 29MAR2005 01NOV2003 30NOV2003 01JAN2004 31JUL2004 01OCT2004 31DEC2004 01JUN2005 31JUL2005 01OCT2005 31JAN2006 01FEB2011 30JUN2011 01JAN2014 28FEB2014 01JAN2015 31JAN2017
2 08JUN2005 01JAN2002 31JAN2002 01DEC2005 28FEB2013 01DEC2016 31DEC2016 01OCT2017 30NOV2017 . . . . . . . .
3 24JUN2005 01JAN2002 31JAN2002 01AUG2002 30SEP2002 01NOV2004 31DEC2004 01JUL2011 31AUG2011 . . . . . . . .
4 18JUL2005 01AUG2005 31DEC2006 01DEC2009 31DEC2010 . . . . . . . . . . . .
5 15AUG2005 01MAY2002 31MAY2002 01MAR2003 31MAY2003 01OCT2003 30NOV2003 01JAN2004 29FEB2004 01APR2004 30APR2004 01APR2006 31MAY2006 01OCT2006 30NOV2006 . .
6 15SEP2005 01MAR2005 31MAR2005 01FEB2006 28FEB2006 . . . . . . . . . . . .
7 17OCT2005 01MAR2005 31MAY2005 01JAN2006 28FEB2006 01FEB2007 28FEB2007 . . . . . . . . . .
8 30OCT2005 01JUN2005 30JUN2005 01AUG2005 30SEP2005 01MAY2006 30JUN2006 01NOV2009 31DEC2009 01MAY2011 30NOV2011 01JAN2013 28FEB2013 01DEC2013 30NOV2014 01MAR2015 31MAY2015
9 10NOV2005 01JUN2004 30JUN2004 01SEP2004 31OCT2004 01MAY2005 30JUN2005 01SEP2006 30NOV2006 01FEB2007 30NOV2007 01NOV2008 31DEC2008 01APR2009 30APR2009 . .
10 17NOV2018 01MAY2005 31JUL2005 01APR2006 31MAY2006 01APR2009 31MAY2009 01APR2010 30APR2010 01APR2011 30JUN2011 01MAR2012 30APR2012 01MAR2013 31MAR2013 01DEC2016 31DEC
11 10DEC2004 01NOV2004 30JUN2008 01OCT2008 30JUN2011 . . . . . . . . . . . .
12 14DEC2004 01NOV2004 31OCT2008 . . . . . . . . . . . . . .
13 01DEC2008 01NOV2004 31OCT2008 01DEC2008 31DEC2016 . . . . . . . . . . . .
14 24DEC2004 01NOV2004 30JUN2005 . . . . . . . . . . . . . . . .
15 01DEC2004 01NOV2005 31JAN2017 . . . . . . . . . . . . . . . .
16 22DEC2005 01NOV2005 31DEC2016 . . . . . . . . . . . . . . . .
17 03DEC2009 01NOV2009 31DEC2016 01NOV2017 31DEC2017 . . . . . . . . . . . .
18 01DEC2010 01NOV2010 31JUL2011 01NOV2013 31OCT2014 . . . . . . . . . . . .
;
data want (drop=imax i days_before days_after dist); set have;
format cov_beg cov_end date9. cov_not 8.;
array cov cov0 cov15 cov30 cov60 cov90 cov120 cov150 cov180;
array beg {*} elig_beg: ;
array end {*} elig_end:;
imax = dim(beg) - nmiss(of elig_beg:);
* Diagnosis in intervals;
do i = 1 to imax;
if beg{i} <= DATE_DIAGNOSIS <= min(end{i},'31dec9999'd) then do;
cov_beg = beg{i};
cov_end = end{i};
dist = 0;
leave;
end;
end;
* No interval found;
if cov_beg = . then do;
* Diagnosis before first start;
if DATE_DIAGNOSIS < beg{1} then do;
cov_beg = beg{1};
cov_end = end{1};
dist = beg{1} - DATE_DIAGNOSIS;
end;
* Diagnosis after last end - only if last start is ended;
else if DATE_DIAGNOSIS > end{imax} and end{imax} ne . then do;
cov_beg = beg{imax};
cov_end = end{imax};
dist = DATE_DIAGNOSIS - end{imax};
end;
* Diagnosis in gap between intervals;
else do i = 2 to imax;
if end{i-1} < DATE_DIAGNOSIS < beg{i} then do;
days_before = DATE_DIAGNOSIS - end{i-1};
days_after = beg{i} - DATE_DIAGNOSIS;
if days_after > days_before then do;
cov_beg = beg{i-1};
cov_end = end{i-1};
dist = days_before;
end;
else do;
cov_beg = beg{i};
cov_end = end{i};
dist = days_after;
end;
leave;
end;
end;
end;
* Set code for date distance;
if dist = 0 then cov{1} = 1;
else if dist <= 15 then cov{2} = 1;
else if dist <= 180 then cov{int((dist-1)/30)+3} = 1;
else cov_not = 1;
run;
... View more