识别重叠用药:SAS社区求助未获正确解决方案
I get it—dealing with overlapping same-drug prescriptions can be tricky, especially when existing code ends up creating unwanted combinations or miscalculating adjusted dates. Let's walk through how to fix this properly.
First, let's recap your core requirements:
- For the same patient and same drug, when a new prescription starts before the previous one ends, we need to adjust the new prescription's start date to the day after the prior prescription ends, then calculate the new end date based on the days supply.
- We also need to track the overlap days between the original prescription dates and the adjusted ones.
Step 1: Sort Your Data
First, make sure your data is sorted by ID, DRUG, and START_DT—this is critical for processing prescriptions in chronological order.
proc sort data=have out=have_sorted; by ID DRUG START_DT; run;
Step 2: Adjust Prescription Dates & Calculate Overlap
Here's the corrected SAS code to handle the overlap adjustment and compute overlap days. We'll use RETAIN to carry forward the previous adjusted end date, and calculate how many days the original new prescription overlapped with the prior one.
data adjusted_prescriptions; set have_sorted; by ID DRUG; format START_DT END_DT ADJ_START_DT ADJ_END_DT date9.; * Retain the adjusted end date from the previous record for the same ID/Drug; retain ADJ_PREV_END; * Initialize adjusted dates and overlap for the first record of each ID/Drug group; if first.DRUG then do; ADJ_START_DT = START_DT; ADJ_END_DT = END_DT; OVERLAP_DAYS = 0; ADJ_PREV_END = ADJ_END_DT; end; else do; * Calculate overlap days: if original start <= previous adjusted end, overlap is (previous adjusted end - original start + 1); if START_DT <= ADJ_PREV_END then do; OVERLAP_DAYS = ADJ_PREV_END - START_DT + 1; ADJ_START_DT = ADJ_PREV_END + 1; ADJ_END_DT = ADJ_START_DT + DAYS_SUPP - 1; * Subtract 1 because days supply is the number of days covered; end; else do; OVERLAP_DAYS = 0; ADJ_START_DT = START_DT; ADJ_END_DT = END_DT; end; * Update the retained adjusted end date; ADJ_PREV_END = ADJ_END_DT; end; drop ADJ_PREV_END; run;
Let's Test This With Your Sample Data
Using your example data:
| ID | DRUG | START_DT | DAYS_SUPP | END_DT |
|---|---|---|---|---|
| 1 | A | 2/17/2010 | 30 | 3/19/2010 |
| 1 | A | 3/17/2010 | 30 | 4/16/2010 |
| 1 | A | 4/12/2010 | 30 | 5/12/2010 |
| 1 | A | 8/20/2010 | 30 | 9/19/2010 |
| 1 | B | 5/6/2009 | 30 | 6/5/2009 |
The output would look like this:
| ID | DRUG | START_DT | DAYS_SUPP | END_DT | ADJ_START_DT | ADJ_END_DT | OVERLAP_DAYS |
|---|---|---|---|---|---|---|---|
| 1 | A | 17FEB2010 | 30 | 19MAR2010 | 17FEB2010 | 19MAR2010 | 0 |
| 1 | A | 17MAR2010 | 30 | 16APR2010 | 20MAR2010 | 19APR2010 | 3 |
| 1 | A | 12APR2010 | 30 | 12MAY2010 | 20APR2010 | 19MAY2010 | 8 |
| 1 | A | 20AUG2010 | 30 | 19SEP2010 | 20AUG2010 | 19SEP2010 | 0 |
| 1 | B | 06MAY2009 | 30 | 05JUN2009 | 06MAY2009 | 05JUN2009 | 0 |
Key Fixes From Your Original Code
- Using
BY GROUPProcessing: Instead ofLAGfunctions, usingfirst.DRUGensures we correctly reset values when moving to a new drug for the same patient—this avoids issues with lagged values from different drugs. - Correct End Date Calculation: When adjusting,
ADJ_END_DTis calculated asADJ_START_DT + DAYS_SUPP - 1because days supply counts the number of days covered (e.g., 30 days starting on 20MAR2010 ends on 19APR2010, not 20APR2010). - Overlap Day Calculation: We explicitly compute how many days the original prescription overlapped with the prior adjusted end date, which is useful for your reporting needs.
Total Overlap Days for a Patient/Drug
If you want to sum the total overlap days per patient and drug, you can use PROC SUMMARY:
proc summary data=adjusted_prescriptions nway; class ID DRUG; var OVERLAP_DAYS; output sum=Total_Overlap_Days; run;
This will give you the total number of overlapping days for each patient-drug combination.
内容的提问来源于stack exchange,提问作者Riya Arora

