Published on :
Statistic INTERNAL_CREATION

Calculation of Percent of Days Covered (PDC) per patient

This code is also available in: Deutsch Español Français
Awaiting validation
This SAS© script implements an algorithm to assess adherence to medication treatment. It begins by generating a dummy dataset ('fills') simulating prescriptions for 100 patients. Each record contains a patient ID, the dispensing date, and the duration of treatment. Then, the script sorts this data by patient and date. The main DATA step processes this data patient by patient to calculate PDC over several consecutive time intervals (defined by macro variables &interv and &ninterv). The algorithm 'stacks' coverage days for each prescription to determine continuous coverage. The final result is a table ('pdc_ptlev') containing one row per patient, with the PDC calculated for each interval, allowing for an analysis of treatment continuity.
Data Analysis

Type : INTERNAL_CREATION


The input dataset 'fills' is entirely generated procedurally in the first DATA step. It does not depend on any external data source. It serves only as an example for the PDC calculation algorithm.

1 Code Block
DATA STEP Data
Explanation :
This block creates a test dataset named 'fills'. It simulates prescription data for 100 patients by generating an identifier (patientICN), a dispensing date (edate), a treatment duration (days), and an optional death date (dod) for censoring. Values are randomly generated to create a realistic dataset for demonstration.
Copied!
1DATA fills;
2LENGTH patientICN 5 dod edate days 5;
3FORMAT edate date9.;
4array T {5} _temporary_ (30, 30, 30, 90, 10);
5DO i=1 to 100;
6 patientICN=1000+i;
7 edate='01Jan2020'd + int(ranuni(0)*100);
8 slack=int(rand('erlang', 2)*10);
9 dod=.;
10 IF ranuni(0)<0.15 THEN dod=edate+int(ranuni(0)*730);
11 DO while (1);
12 days=T[int(ranuni(0)*dim(T)+1)];
13 OUTPUT;
14 edate+max(1,int(days+rand('normal')*5))+slack;
15 IF ranuni(0)<.05 THEN leave;
16 END;
17END;
18drop i;
19RUN;
2 Code Block
PROC PRINT
Explanation :
Displays the first 30 observations of the 'fills' dataset that has just been created. This allows for a quick visual check to ensure that the test data has been generated correctly.
Copied!
1title 'first 50 obs of fake input
2data';
3PROC PRINT
4DATA=fills (obs=30);
5 
6RUN;
7 
3 Code Block
PROC SORT
Explanation :
Sorts the 'fills' dataset by patient ID (patientICN) and then by dispensing date (edate). This step is crucial for the sequential processing by patient performed in the next calculation block.
Copied!
1PROC SORT DATA=fills; BY patientICN edate; RUN;
4 Code Block
DATA STEP Data
Explanation :
This block is the core of the algorithm. It reads the sorted data and, for each patient, calculates the medication coverage days. Using `first.patientICN` and `last.patientICN` instructions, it initializes and finalizes calculations for each individual. It iterates through prescriptions, 'stacks' coverage days, and increments the counter for the correct time interval. At the end of a patient's data, it calculates the PDC for each interval and generates a single output row for that patient in the 'pdc_ptlev' table.
Copied!
1%let interv=90; * number of days in interval ;
2%let ninterv=12; * number of intervals ;
3 
4DATA pdc_ptlev;
5SET fills;
6BY patientICN edate;
7LENGTH currend 5 currpos 3 bndry 3 pdc_p1-pdc_p&ninterv 5;
8retain currend currpos pdc_:;
9array p {*} pdc_:;
10array ends {&ninterv} _temporary_;
11array D {&ninterv} _temporary_;
12IF first.patientICN THEN DO;
13 currend=.;
14 currpos=1;
15 bndry=0;
16 DO i=1 to dim(p);
17 p[i]=0;
18 bndry+&interv;
19 ends[i]=edate+bndry;
20 D[i]=min(&interv,max(0/(DOD>.),&interv-(ends[i]-DOD)));
21 END;
22END;
23 
24currend=max(currend, edate);
25DO while (days>0);
26 currend+1;
27 days=days-1;
28 IF currend>ends[dim(ends)] or .THEN leave;
29 DO while (ends[currpos]<=currend and currpos
30 currpos+1;
31 END;
32 p[currpos]+1;
33END;
34 
35IF last.patientICN THEN DO;
36 DO i=1 to dim(p);
37 p[i]=p[i]/D[i];
38 END;
39 OUTPUT;
40END;
41keep patientICN pdc_:;
42FORMAT pdc_: percent8.1;
43RUN;
5 Code Block
PROC PRINT
Explanation :
Displays the first 30 observations of the final 'pdc_ptlev' dataset. Each row represents a patient, and the columns show the PDC for each interval. The `heading=v` option allows for vertical display of headers for better readability.
Copied!
1title 'first 30 obs of output -- one row/patient';
2PROC PRINT
3DATA=pdc_ptlev (obs=30) heading=v width=min;
4 
5RUN;
6title;
7 
This material is provided "as is" by We Are Cas. There are no warranties, expressed or implied, as to merchantability or fitness for a particular purpose regarding the materials or code contained herein. We Are Cas is not responsible for errors in this material as it now exists or will exist, nor does We Are Cas provide technical support for it.
Copyright Info : J Smith Jul 2023