/******************************************************************************************** **** Program name: PSSA Macro **** **** Author: Earl Morris **** **** Special thanks to Dr. Rose Jiang and Dr. Scott Vouri for valuable input on this macro. ********************************************************************************************/ libname t '/data/rawdata/Truven'; /* Input the libname and destination path for the folder you desire. */ libname morris '/data/resultdata/Vouri/TruvenRxCascadePSSA_2019_007/earl.morris/TEST/'; %macro PSSA(yr_v, index_class, index_drugs, marker_class, marker_drugs, neg_control_class, neg_control_drugs, subgrp); /* library - Input the libname for the file destination folder you desire. */ %let library = morris; /* redbook - Input the most current Redbook file name. */ %let redbook = redbook_18; /* enrollment - Input the most current eligibility file name. */ %let enrollment = truven_cts_elig_rx_cc_mc_0519; /* cc - Input Y to include IBM MarketScan Commercial Claims. Input N to exclude IBM MarketScan Commercial Claims. */ %let cc = Y; /* mc - Input Y to include IBM MarketScan Medicare Supplemental Claims. Input N to exclude IBM MarketScan Medicare Supplemental Claims. */ %let mc = Y; /* index_mstfmds - Input the Master Form Descriptions to be included for the *INDEX DRUG*, in single quotes separated by commas. Of note, 'Capsule' will include any drugs with Master Form Description starting with 'Capsule', i.e. 'Capsule, Delayed Release', etc. */ %let index_mstfmds = ('Capsule', 'Tablet'); /* index_roacd - Input the Route of Administration Codes to be included for the *INDEX DRUG*, in single quotes separated by commas. */ %let index_roacd = ('PO'); /* marker_mstfmds - Input the Master Form Descriptions to be included for the *MARKER DRUG*, in single quotes separated by commas. Of note, 'Capsule' will include any drugs with Master Form Description starting with 'Capsule', i.e. 'Capsule, Delayed Release', etc. */ %let marker_mstfmds = ('Capsule', 'Tablet'); /* marker_roacd - Input the Route of Administration Codes to be included for the *MARKER DRUG*, in single quotes separated by commas. */ %let marker_roacd = ('PO'); /* neg_control_mstfmds - Input the Master Form Descriptions to be included for the *NEGATIVE CONTROL DRUG*, in single quotes separated by commas. Of note, 'Capsule' will include any drugs with Master Form Description starting with 'Capsule', i.e. 'Capsule, Delayed Release', etc. */ %let neg_control_mstfmds = ('Capsule', 'Tablet'); /* neg_control_roacd - Input the Route of Administration Codes to be included for the *NEGATIVE CONTROL DRUG*, in single quotes separated by commas. */ %let neg_control_roacd = ('PO'); /* enrollment_before - Input the number of days of continuous enrollment BEFORE index drug initiation to be required */ %let enrollment_before = 360; /* enrollment_after - Input the number of days of continuous enrollment AFTER index drug initiation to be required */ %let enrollment_after = 360; /* diag_before - Input the number of days BEFORE index drug initiation to be searched for diagnosis codes */ %let diag_before = 360; /* diag_after - Input the number of days AFTER index drug initiation to be searched for diagnosis codes */ %let diag_after = 360; /* exc_diag_yn - Input Y if excluding patients with a certain algorithm of ICD codes. Input N if NOT excluding patients with a certain algoritm of ICD codes. */ %let exc_diag_yn = N; /* exc_diag_icd - Input the array of ICD-9 and ICD-10 codes to be excluded in single quotes separated by commas. Of note, this will exclude patients with >/= 1 claim with a diagnosis code in the algorithm of interest. If no exclusion criteria on diagnosis code, just enter ('1') */ %let exc_diag_icd = ('1'); /* comorbid_1_yn, comorbid_2_yn, comorbid_3_yn - Input Y if subgrouping patients with a certain algorithm of ICD codes. Input N if NOT subgrouping patients with a certain algorithm of ICD codes. Of note, this macro allows you to subgroup patients using up to three different algorithms of ICD-9 and ICD-10 codes. If only one subgroup of interest, enter Y for comorbid_1_yn and N for comorbid_2_yn and comorbid_3_yn. If two subgroups of interest, enter Y for comorbid_1_yn and comorbid_2_yn and N for comorbid_3_yn. If three subgroups of interest, enter Y for comorbid_1_yn, comorbid_2_yn, and comorbid_3_yn.*/ %let comorbid_1_yn = N; %let comorbid_2_yn = N; %let comorbid_3_yn = N; /* comorbid_icd_1, comorbid_icd_2, comorbid_icd_3 - Input the array of ICD-9 and ICD-10 codes to be subgrouped in single quotes separated by commas. Of note, this will subgroup patients with >/= 1 claim with a diagnosis code in the algorithm of interest. If no subgroup on diagnosis code desired, just enter ('1') */ %let comorbid_icd_1 = ('1'); %let comorbid_icd_2 = ('1'); %let comorbid_icd_3 = ('1'); /* age_low - Input the minimum age in years an individual must be to be included in the analysis */ %let age_low = 18; /* age_high - Input the maximum age in years an individual must be to be included in the analysis */ %let age_high = 90; /* PSSA_before_after_1, PSSA_before_after_2, PSSA_before_after_3 - Input the maximum number of days required between index drug and marker drug initiation to be included in the analysis. Of note, this macro allows you to conduct up to three different analyses with different time intervals. Jesper Hallas, who published the proof-of-concept paper for PSSA, recommends a max time interval of 360 days. If conducting PSSA analyses with multiple time intervals, order them in descending order. For example, if conducting three PSSA analyses with time intervals of 360 days, 180 days, and 90 days... Input PSSA_before_after_1 = 360, PSSA_before_after_2 = 180, PSSA_before_after_3 = 90 If conducting two PSSA analyses with time intervals of 360 days and 180 days... Input PSSA_before_after_1 = 360, PSSA_before_after_2 = 180, PSSA_before_after_3 = 0 The macro knows to skip over any let statements with PSSA_before_after_i = 0 */ %let PSSA_before_after_1 = 360; %let PSSA_before_after_2 = 180; %let PSSA_before_after_3 = 90; /* CI - Input the confidence interval (number only [without %]) for adjusted sequence ratio desired. To account for multiple testing, some authors use 99% confidence intervals. This macro allows options of 90%, 95%, 99%, and 99.9%. */ %let CI = 99; /* year_1, year_2, year_3, year_4 - Although PSSA inherently adjusts for secular trends in prescribing of drugs, it is helpful to investigate if there are any major differences in adjusted sequence ratios among subgroups of the total number of years of data included. This macro conducts subgroup analyses among three subgroups of year ranges. Let year_1 equal the first year of data included... i.e. 2005 Let year_2 equal the lower limit of subgroup 2... i.e. 2011 Let year_3 equal the lower limit of subgroup 3... i.e. 2015 Let year_4 equal the upper limit of subgroup 3... i.e. 2018 For example, the above let statements would make subgroup 1 be 2005-2010, subgroup 2 be 2011-2014, and subgroup 3 be 2015-2019 */ %let year_1 = 2005; %let year_2 = 2007; %let year_3 = 2009; %let year_4 = 2010; /* min_days, max_days - To perform the PSSA analysis, SAS requires the stored value for the first and last date of data included in the study. In other words, this is the number of elapsed days since January 1, 1960. Let min_days equal the stored value for the first day of data included. For January 1, 2005, input 16437. Let max_days equal the stored value for the last day of data included. For December 31, 2018, input 21549. Use https://www.sastipsbyhal.com/2012/01/sas-date-calculator-now-available.html and replace Date: 1/1/1960 with the date of interest to find these values. */ %let min_days = 16437; %let max_days = 21914; /*****************************************************************************************************/ /* Identifying INDEX DRUG NDCs from Redbook */ %do i=1 %to %sysfunc(countw(&index_drugs)); %let index_drug_scan = %scan(&index_drugs, &i); /* Scanning the INDEX DRUG names included in the macro to identify NDCs from Redbook and further only including those NDCs which correspond to drugs with the master form description and route of administration desired. */ data ndc_index_drug_&i (keep=GENNME NDCNUM MSTFMDS ROACD); set t.&redbook; where index(upcase(GENNME),"&index_drug_scan") >0 and ROACD in: &index_roacd and MSTFMDS in: &index_mstfmds; run; %end; /* Concatenating NDCs for all drugs within the class of INDEX DRUGS desired. Keeping only generic name and NDC */ data ndc_&index_class (keep=NDCNUM GENNME); set ndc_index_drug_1-ndc_index_drug_%sysfunc(countw(&index_drugs)); run; /* Removing any duplicate NDCs and storing the full list of INDEX DRUG NDCs in library. */ proc sort data=ndc_&index_class out=&library..ndc_&index_class nodupkey; by _all_; run; %do i=1 %to %sysfunc(countw(&index_drugs)); /* Deleting unneeded intermediate data sets used to identify INDEX DRUG NDCs. */ proc delete data=ndc_index_drug_&i ndc_&index_class (gennum=all); run; %end; /* Identifying MARKER DRUG NDCs from Redbook */ %do i=1 %to %sysfunc(countw(&marker_drugs)); %let marker_drug_scan = %scan(&marker_drugs, &i); /* Scanning the MARKER DRUG names included in the macro to identify NDCs from Redbook and further only including those NDCs which correspond to drugs with the master form description and route of administration desired. */ data ndc_marker_drug_&i (keep=GENNME NDCNUM MSTFMDS ROACD); set t.&redbook; where index(upcase(GENNME),"&marker_drug_scan") > 0 and ROACD in: &marker_roacd and MSTFMDS in: &marker_mstfmds; run; %end; /* Concatenating NDCs for all drugs within the class of MARKER DRUGS desired. Keeping only generic name and NDC */ data ndc_&marker_class (keep=NDCNUM GENNME); set ndc_marker_drug_1-ndc_marker_drug_%sysfunc(countw(&marker_drugs)); run; /* Removing any duplicate NDCs and storing the full list of MARKER DRUG NDCs in library. */ proc sort data=ndc_&marker_class out=&library..ndc_&marker_class nodupkey; by _all_; run; %do i=1 %to %sysfunc(countw(&marker_drugs)); /* Deleting unneeded intermediate data sets used to identify INDEX DRUG NDCs. */ proc delete data=ndc_marker_drug_&i ndc_&marker_class (gennum=all); run; %end; /* Identifying NEGATIVE CONTROL NDCs from Redbook */ %do i=1 %to %sysfunc(countw(&neg_control_drugs)); %let neg_control_drug_scan = %scan(&neg_control_drugs, &i); /* Scanning the NEGATIVE CONTROL DRUG names included in the macro to identify NDCs from Redbook and further only including those NDCs which correspond to drugs with the master form description and route of administration desired. */ data ndc_neg_control_drug_&i (keep=GENNME NDCNUM MSTFMDS ROACD); set t.&redbook; where index(upcase(GENNME),"&neg_control_drug_scan") > 0 and ROACD in: &neg_control_roacd and MSTFMDS in: &neg_control_mstfmds; run; %end; /* Concatenating NDCs for all drugs within the class of NEGATIVE CONTROL DRUGS desired. Keeping only generic name and NDC */ data ndc_&neg_control_class (keep=NDCNUM GENNME); set ndc_neg_control_drug_1-ndc_neg_control_drug_%sysfunc(countw(&neg_control_drugs)); run; /* Removing any duplicate NDCs and storing the full list of NEGATIVE CONTROL DRUG NDCs in library. */ proc sort data=ndc_&neg_control_class out=&library..ndc_&neg_control_class nodupkey; by _all_; run; %do i=1 %to %sysfunc(countw(&neg_control_drugs)); /* Deleting unneeded intermediate data sets used to identify NEGATIVE CONTROL DRUG NDCs. */ proc delete data=ndc_neg_control_drug_&i ndc_&neg_control_class (gennum=all); run; %end; /*****************************************************************************************************/ /*Selecting INDEX/MARKER DRUG use records*/ %do i=1 %to %sysfunc(countw(&yr_v)); %let scanyr = %scan(&yr_v, &i); %if &cc = Y %then %do; /* Performing a left join of INDEX DRUG NDCs to commercial pharmacy claims for every year of included data. */ proc sql; create table cc_&index_class._&i as select a.*, b.NDCNUM, b.SVCDATE, b.ENROLID, b.DAYSUPP, b.METQTY from &library..ndc_&index_class a left join t.cc_rx_&scanyr b on a.NDCNUM=b.NDCNUM; /* Deleting claims with a missing enrollee ID */ data cc_&index_class._&i; set cc_&index_class._&i; if enrolid=. then delete; run; %end; /* Joining Medicare supplemental claims rx file from each year with INDEX DRUG NDCs */ %if &mc = Y %then %do; /* Performing a left join of INDEX DRUG NDCs to Medicare supplemental pharmacy claims for every year of included data. */ proc sql; create table mc_&index_class._&i as select a.*, b.NDCNUM, b.SVCDATE, b.ENROLID, b.DAYSUPP, b.METQTY from &library..ndc_&index_class a left join t.mc_rx_&scanyr b on a.NDCNUM=b.NDCNUM; /* Deleting claims with a missing enrollee ID */ data mc_&index_class._&i; set mc_&index_class._&i; if enrolid=. then delete; run; %end; /* Joining commercial claims rx file from each year with MARKER DRUG NDCs */ %if &cc = Y %then %do; /* Performing a left join of MARKER DRUG NDCs to commercial pharmacy claims for every year of included data. */ proc sql; create table cc_&marker_class._&i as select a.*, b.NDCNUM, b.SVCDATE, b.ENROLID, b.DAYSUPP, b.METQTY from &library..ndc_&marker_class a left join t.cc_rx_&scanyr b on a.NDCNUM=b.NDCNUM; /* Deleting claims with a missing enrollee ID */ data cc_&marker_class._&i; set cc_&marker_class._&i; if enrolid=. then delete; run; %end; /* Joining Medicare supplemental claims rx file from each year with MARKER DRUG NDCs */ %if &mc = Y %then %do; /* Performing a left join of MARKER DRUG NDCs to Medicare supplemental pharmacy claims for every year of included data. */ proc sql; create table mc_&marker_class._&i as select a.*, b.NDCNUM, b.SVCDATE, b.ENROLID, b.DAYSUPP, b.METQTY from &library..ndc_&marker_class a left join t.mc_rx_&scanyr b on a.NDCNUM=b.NDCNUM; /* Deleting claims with a missing enrollee ID */ data mc_&marker_class._&i; set mc_&marker_class._&i; if enrolid=. then delete; run; %end; /* Joining commercial claims rx file from each year with NEGATIVE CONTROL DRUG NDCs */ %if &cc = Y %then %do; /* Performing a left join of MARKER DRUG NDCs to commercial pharmacy claims for every year of included data. */ proc sql; create table cc_&neg_control_class._&i as select a.*, b.NDCNUM, b.SVCDATE, b.ENROLID, b.DAYSUPP, b.METQTY from &library..ndc_&neg_control_class a left join t.cc_rx_&scanyr b on a.NDCNUM=b.NDCNUM; /* Deleting claims with a missing enrollee ID */ data cc_&neg_control_class._&i; set cc_&neg_control_class._&i; if enrolid=. then delete; run; %end; /* Joining Medicare supplemental claims rx file from each year with NEGATIVE CONTROL drug NDCs */ %if &mc = Y %then %do; /* Performing a left join of MARKER DRUG NDCs to Medicare supplemental pharmacy claims for every year of included data. */ proc sql; create table mc_&neg_control_class._&i as select a.*, b.NDCNUM, b.SVCDATE, b.ENROLID, b.DAYSUPP, b.METQTY from &library..ndc_&neg_control_class a left join t.mc_rx_&scanyr b on a.NDCNUM=b.NDCNUM; quit; /* Deleting claims with a missing enrollee ID */ data mc_&neg_control_class._&i; set mc_&neg_control_class._&i; if enrolid=. then delete; run; %end; %end; /********************************************************************************/ /* Concatenating INDEX DRUG commercial and/or Medicare supplement pharmacy claims for all years. */ data all_rx_&index_class; set %if &cc = Y %then %do; cc_&index_class._1-cc_&index_class._%sysfunc(countw(&yr_v)) %end; %if &mc = Y %then %do; mc_&index_class._1-mc_&index_class._%sysfunc(countw(&yr_v)) %end; ; run; /* Removing any duplicate INDEX DRUG pharmacy claims. */ proc sort data=all_rx_&index_class nodupkey; by _all_; run; /* Sorting INDEX DRUG pharmacy claims by enrollee ID and service date. */ proc sort data=all_rx_&index_class; by enrolid svcdate; run; /* Removing claims with days supply <=0 and > 365, renaming svcdate variable to index_dt_&index_class for later merges and outputing first INDEX DRUG pharmacy claim for each enrollee ID. */ data newuser_&index_class; set all_rx_&index_class (rename=(svcdate=index_dt_&index_class)); by enrolid; if daysupp <=0 or daysupp > 365 then delete; if first.enrolid then output; run; /* PROC MEANS to identify total number of INDEX DRUG new users before applying enrollment criteria */ proc means data=newuser_&index_class n; var enrolid; title "New Users of &index_class - Before Eligibility"; run; /* Inner joining INDEX DRUG new users to enrollment file */ proc sql; create table enrollment_&index_class as select a.*, b.* from newuser_&index_class a inner join t.&enrollment b on a.enrolid=b.enrolid; quit; /* Identifying new users of INDEX DRUG with continuous enrollment and renaming gennme variable to &index_class for later merges. */ data &library..continuous_&index_class (rename=(gennme=&index_class)); set enrollment_&index_class; if index_dt_&index_class-dtstart<&enrollment_before then delete; if dtend-index_dt_&index_class<&enrollment_after then delete; run; /* PROC MEANS to identify total number of INDEX DRUG new users after applying enrollment criteria */ proc means data=&library..continuous_&index_class n; var enrolid; title "New Users of &index_class - Continuous Enrollment &enrollment_before Days before and &enrollment_after Days after Index Date"; run; /********************************************************************************/ /* Concatenating MARKER DRUG commercial and/or Medicare supplement pharmacy claims for all years. */ data all_rx_&marker_class; set %if &cc = Y %then %do; cc_&marker_class._1-cc_&marker_class._%sysfunc(countw(&yr_v)) %end; %if &mc = Y %then %do; mc_&marker_class._1-mc_&marker_class._%sysfunc(countw(&yr_v)) %end; ; run; /* Removing any duplicate MARKER DRUG pharmacy claims. */ proc sort data=all_rx_&marker_class nodupkey; by _all_; run; /* Sorting MARKER DRUG pharmacy claims by enrollee ID and service date. */ proc sort data=all_rx_&marker_class; by enrolid svcdate; run; /* Removing claims with days supply <=0 and > 365, renaming svcdate variable to index_dt_&marker_class for later merges and outputing first INDEX DRUG pharmacy claim for each enrollee ID. */ data newuser_&marker_class; set all_rx_&marker_class (rename=(svcdate=index_dt_&marker_class)); by enrolid; if daysupp <=0 or daysupp > 365 then delete; if first.enrolid then output; run; /* PROC MEANS to identify total number of MARKER DRUG new users before applying enrollment criteria */ proc means data=newuser_&marker_class n; var enrolid; title "New Users of &marker_class - Before Eligibility"; run; /* Inner joining MARKER DRUG new users to enrollment file */ proc sql; create table enrollment_&marker_class as select a.*, b.* from newuser_&marker_class a inner join t.&enrollment b on a.enrolid=b.enrolid; quit; /* Identifying new users of MARKER DRUG with continuous enrollment and renaming gennme variable to &marker_class for later merges. */ data &library..continuous_&marker_class (rename=(gennme=&marker_class)); set enrollment_&marker_class; if index_dt_&marker_class-dtstart<&enrollment_before then delete; if dtend-index_dt_&marker_class<&enrollment_after then delete; run; /* PROC MEANS to identify total number of INDEX DRUG new users after applying enrollment criteria */ proc means data=&library..continuous_&marker_class n; var enrolid; title "New Users of &marker_class - Continuous Enrollment &enrollment_before Days before and &enrollment_after Days after Index Date"; run; /*********************************************************************************/ /* Concatenating NEGATIVE CONTROL DRUG commercial and/or Medicare supplement pharmacy claims for all years. */ data all_rx_&neg_control_class; set %if &cc = Y %then %do; cc_&neg_control_class._1-cc_&neg_control_class._%sysfunc(countw(&yr_v)) %end; %if &mc = Y %then %do; mc_&neg_control_class._1-mc_&neg_control_class._%sysfunc(countw(&yr_v)) %end; ; run; /* Removing any duplicate NEGATIVE CONTROL DRUG pharmacy claims. */ proc sort data=all_rx_&neg_control_class nodupkey; by _all_; run; /* Sorting NEGATIVE CONTROL DRUG pharmacy claims by enrollee ID and service date. */ proc sort data=all_rx_&neg_control_class; by enrolid svcdate; run; /* Removing claims with days supply <=0 and > 365, renaming svcdate variable to index_dt_&neg_control_class for later merges and outputing first NEGATIVE DRUG pharmacy claim for each enrollee ID. */ data newuser_&neg_control_class; set all_rx_&neg_control_class (rename=(svcdate=index_dt_&neg_control_class)); by enrolid; if daysupp <=0 or daysupp > 365 then delete; if first.enrolid then output; run; /* PROC MEANS to identify total number of NEGATIVE CONTROL DRUG new users before applying enrollment criteria */ proc means data=newuser_&neg_control_class n; var enrolid; title "New Users of &neg_control_class - Before Eligibility"; run; /* Inner joining NEGATIVE CONTROL DRUG new users to enrollment file */ proc sql; create table enrollment_&neg_control_class as select a.*, b.* from newuser_&neg_control_class a inner join t.&enrollment b on a.enrolid=b.enrolid; quit; /* Identifying new users of NEGATIVE CONTROL DRUG with continuous enrollment and renaming gennme variable to &neg_control_class for later merges. */ data &library..continuous_&neg_control_class (rename=(gennme=&neg_control_class)); set enrollment_&neg_control_class; if index_dt_&neg_control_class-dtstart<&enrollment_before then delete; if dtend-index_dt_&neg_control_class<&enrollment_after then delete; run; /* PROC MEANS to identify total number of NEGATIVE CONTROL DRUG new users after applying enrollment criteria */ proc means data=&library..continuous_&neg_control_class n; var enrolid; title "New Users of &neg_control_class - Continuous Enrollment &enrollment_before Days before and &enrollment_after Days after Index Date"; run; /* Deleting intermediate files used to identify continuous enrollment. */ %do i=1 %to %sysfunc(countw(&yr_v)); proc delete data= %if &cc = Y %then %do; cc_&index_class._&i cc_&marker_class._&i cc_&neg_control_class._&i %end; %if &mc = Y %then %do; mc_&index_class._&i mc_&marker_class._&i mc_&neg_control_class._&i %end; (gennum=all); run; %end; proc delete data= all_rx_&index_class newuser_&index_class enrollment_&index_class all_rx_&marker_class newuser_&marker_class enrollment_&marker_class all_rx_&neg_control_class newuser_&neg_control_class enrollment_&neg_control_class (gennum=all); run; /*************************************************************/ /* Identify exclusion and/or comorbid diagnoses for INDEX DRUG new users */ /*************************************************************/ /* Selecting both commercial claims and Medicare supplemental encounter claims */ %if &exc_diag_yn = Y or &comorbid_1_yn = Y or &comorbid_2_yn = Y or &comorbid_3_yn =Y %then %do; %do i=1 %to %sysfunc(countw(&yr_v)); %let scanyr = %scan(&yr_v, &i); %if &cc = Y %then %do; /* Inner join to identify inpatient admission commercial claims for INDEX DRUG new users for each year*/ proc sql; create table cc_ip_adm_&index_class._&i as select a.*, b.index_dt_&index_class from t.cc_ip_adm_&scanyr (keep=enrolid admdate dx:) a inner join &library..continuous_&index_class b on a.enrolid=b.enrolid; quit; /* Inner join to identify inpatient service commercial claims for INDEX DRUG new users for each year*/ proc sql; create table cc_ip_svc_&index_class._&i as select a.*, b.index_dt_&index_class from t.cc_ip_svc_&scanyr (keep=enrolid svcdate dx:) a inner join &library..continuous_&index_class b on a.enrolid=b.enrolid; quit; /* Inner join to identify outpatient service commercial claims for INDEX DRUG new users for each year*/ proc sql; create table cc_ot_svc_&index_class._&i as select a.*, b.index_dt_&index_class from t.cc_ot_svc_&scanyr (keep=enrolid svcdate dx:) a inner join &library..continuous_&index_class b on a.enrolid=b.enrolid; quit; %end; %if &mc = Y %then %do; /* Inner join to identify inpatient admission Medicare supplemental claims for INDEX DRUG new users for each year*/ proc sql; create table mc_ip_adm_&index_class._&i as select a.*, b.index_dt_&index_class from t.mc_ip_adm_&scanyr (keep=enrolid admdate dx:) a inner join &library..continuous_&index_class b on a.enrolid=b.enrolid; quit; /* Inner join to identify inpatient service Medicare supplemental claims for INDEX DRUG new users for each year*/ proc sql; create table mc_ip_svc_&index_class._&i as select a.*, b.index_dt_&index_class from t.mc_ip_svc_&scanyr (keep=enrolid svcdate dx:) a inner join &library..continuous_&index_class b on a.enrolid=b.enrolid; quit; /* Inner join to identify outpatient service Medicare supplemental claims for INDEX DRUG new users for each year*/ proc sql; create table mc_ot_svc_&index_class._&i as select a.*, b.index_dt_&index_class from t.mc_ot_svc_&scanyr (keep=enrolid svcdate dx:) a inner join &library..continuous_&index_class b on a.enrolid=b.enrolid; quit; %end; %end; /* Concatenating inpatient admission claims for INDEX DRUG new users for each year */ data ip_adm_all_&index_class (rename=(admdate=svcdate)); set %if &cc = Y %then %do; cc_ip_adm_&index_class._1-cc_ip_adm_&index_class._%sysfunc(countw(&yr_v)) %end; %if &mc = Y %then %do; mc_ip_adm_&index_class._1-mc_ip_adm_&index_class._%sysfunc(countw(&yr_v)) %end; ; run; /* Removing duplicate inpatient admission claims for INDEX DRUG new users */ proc sort data=ip_adm_all_&index_class nodupkey; by _all_; run; /* Concatenating inpatient service claims for INDEX DRUG new users for each year */ data ip_svc_all_&index_class; set %if &cc = Y %then %do; cc_ip_svc_&index_class._1-cc_ip_svc_&index_class._%sysfunc(countw(&yr_v)) %end; %if &mc = Y %then %do; mc_ip_svc_&index_class._1-mc_ip_svc_&index_class._%sysfunc(countw(&yr_v)) %end; ; run; /* Removing duplicate inpatient service claims for INDEX DRUG new users */ proc sort data=ip_svc_all_&index_class nodupkey; by _all_; run; /* Concatenating outpatient service claims for INDEX DRUG new users for each year */ data ot_svc_all_&index_class; set %if &cc = Y %then %do; cc_ot_svc_&index_class._1-cc_ot_svc_&index_class._%sysfunc(countw(&yr_v)) %end; %if &mc = Y %then %do; mc_ot_svc_&index_class._1-mc_ot_svc_&index_class._%sysfunc(countw(&yr_v)) %end; ; run; /* Removing duplicate outpatient service claims for INDEX DRUG new users */ proc sort data=ot_svc_all_&index_class nodupkey; by _all_; run; /* Concatenating all inpatient and outpatient claims for INDEX DRUG new users. */ data &index_class._diagnosis; set ip_adm_all_&index_class ip_svc_all_&index_class ot_svc_all_&index_class; where (index_dt_&index_class - &diag_before)= &age_low and year(index_dt_&index_class)-dobyr <= &age_high; run; /* PROC MEANS to count total number of INDEX DRUG new users who meet age requirements */ proc means data=&library..&index_class._exc_age n; var enrolid; title "New Users of &index_class - Age >= &age_low and <= &age_high "; run; %do i=1 %to %sysfunc(countw(&yr_v)); %let scanyr = %scan(&yr_v, &i); /****NEGATIVE CONTROL DRUG DEMOGRAPHICS*****/ %if &cc = Y %then %do; /* Inner joining NEGATIVE CONTROL DRUG new users without exclusion diagnoses to the enrollment demographics file for commercial claims for each year */ proc sql; create table cc_&neg_control_class._demo_&i as select a.*, b.dobyr, b.sex, b.plantyp, b.region, b.datatyp, b.rx, b.hlthplan from &library..&neg_control_class._wo_excl a inner join t.cc_enr_det_&scanyr b on a.enrolid=b.enrolid where b.dtstart <= a.index_dt_&neg_control_class <= b.dtend; quit; %end; %if &mc = Y %then %do; /* Inner joining NEGATIVE CONTROL DRUG new users without exclusion diagnoses to the enrollment demographics file for Medicare supplemental claims for each year */ proc sql; create table mc_&neg_control_class._demo_&i as select a.*, b.dobyr, b.sex, b.plantyp, b.region, b.datatyp, b.rx, b.hlthplan from &library..&neg_control_class._wo_excl a inner join t.mc_enr_det_&scanyr b on a.enrolid=b.enrolid where b.dtstart <= a.index_dt_&neg_control_class <= b.dtend; quit; %end; %end; /* Concatenating NEGATIVE CONTROL DRUG new user demographics for each year */ data demo_&neg_control_class; set %if &cc = Y %then %do; cc_&neg_control_class._demo_1-cc_&neg_control_class._demo_%sysfunc(countw(&yr_v)) %end; %if &mc = Y %then %do; mc_&neg_control_class._demo_1-mc_&neg_control_class._demo_%sysfunc(countw(&yr_v)) %end; ; run; /* Removing any duplicate NEGATIVE CONTROL DRUG demographics observations */ proc sort data=demo_&neg_control_class nodupkey; by _all_; run; /* Sorting NEGATIVE CONTROL DRUG new users with demographic information by enrollee ID and service date */ proc sort data=demo_&neg_control_class; by enrolid index_dt_&neg_control_class; run; /* Keeping NEGATIVE CONTROL DRUG new users that meet age requirements and saving data file to library */ data &library..&neg_control_class._exc_age; set demo_&neg_control_class; incidence=1; where year(index_dt_&neg_control_class)-dobyr >= &age_low+2 and year(index_dt_&neg_control_class)-dobyr <= &age_high+2; run; /* PROC MEANS to count total number of INDEX DRUG new users who meet age requirements */ proc means data=&library..&neg_control_class._exc_age n; var enrolid; title "New Users of &neg_control_class - Age >= &age_low and <= &age_high "; run; /* Deleting intermediate files used to identify demographic information for INDEX DRUG and NEGATIVE CONTROL DRUG new users */ %do i=1 %to %sysfunc(countw(&yr_v)); proc delete data= %if &cc = Y %then %do; cc_&index_class._demo_&i cc_&neg_control_class._demo_&i %end; %if &mc = Y %then %do; mc_&index_class._demo_&i mc_&neg_control_class._demo_&i %end; demo_&index_class demo_&neg_control_class (gennum=all); run; %end; /*****************************************************************************************************/ /* Flagging INDEX DRUG new users by age and by year of INDEX DRUG initiation */ data &index_class._age_counts; set &library..&index_class._exc_age; if year(index_dt_&index_class)-dobyr >= 20 and year(index_dt_&index_class)-dobyr < 52 then age_2050=1; if year(index_dt_&index_class)-dobyr >= 52 and year(index_dt_&index_class)-dobyr < 67 then age_5065=1; if year(index_dt_&index_class)-dobyr >= 20 and year(index_dt_&index_class)-dobyr < 67 then age_lt65=1; if year(index_dt_&index_class)-dobyr >= 67 then age_ge65=1; if year(index_dt_&index_class) >= &year_1 and year(index_dt_&index_class) < &year_2 then year_group=1; if year(index_dt_&index_class) >= &year_2 and year(index_dt_&index_class) < &year_3 then year_group=2; if year(index_dt_&index_class) >= &year_3 and year(index_dt_&index_class) <= &year_4 then year_group=3; run; %do i=1 %to %sysfunc(countw(&index_drugs)); %let index_drug_scan = %scan(&index_drugs, &i); /* Identifying INDEX DRUG new users by individual drugs */ data &index_class._initiators_&i; set &library..&index_class._exc_age; where index(upcase(&index_class),"&index_drug_scan") >0; &index_class._days = index_dt_&index_class - 0; &marker_class._days = index_dt_&marker_class - 0; run; /* PROC MEANS to count total number of INDEX DRUG new users by individual drugs */ proc means data=&index_class._initiators_&i n; var enrolid; title "Count of &index_drug_scan Initiators"; run; %end; /* NEGATIVE CONTROL DRUG */ /* Flagging NEGATIVE CONTROL DRUG new users by age and by year of INDEX DRUG initiation */ data &neg_control_class._age_counts; set &library..&neg_control_class._exc_age; if year(index_dt_&neg_control_class)-dobyr >= 20 and year(index_dt_&neg_control_class)-dobyr < 52 then age_2050=1; if year(index_dt_&neg_control_class)-dobyr >= 52 and year(index_dt_&neg_control_class)-dobyr < 67 then age_5065=1; if year(index_dt_&neg_control_class)-dobyr >= 20 and year(index_dt_&neg_control_class)-dobyr < 67 then age_lt65=1; if year(index_dt_&neg_control_class)-dobyr >= 67 then age_ge65=1; if year(index_dt_&neg_control_class) >= &year_1 and year(index_dt_&neg_control_class) < &year_2 then year_group=1; if year(index_dt_&neg_control_class) >= &year_2 and year(index_dt_&neg_control_class) < &year_3 then year_group=2; if year(index_dt_&neg_control_class) >= &year_3 and year(index_dt_&neg_control_class) <= &year_4 then year_group=3; run; /*****************************************************************************************************/ /* Combining INDEX/MARKER Drug use */ /* Left joining to identify individuals who initiated INDEX DRUG and MARKER DRUG */ proc sql; create table combine_&index_class._&marker_class as select a.*, b.&marker_class, b.index_dt_&marker_class from &library..&index_class._exc_age a left join &library..continuous_&marker_class b on a.enrolid=b.enrolid; quit; /* Including only individuals that initiated INDEX DRUG and MARKER DRUG within the prespecified PSSA window */ data &index_class._&marker_class.window; set combine_&index_class._&marker_class; where (index_dt_&index_class - &PSSA_before_after_1) <= index_dt_&marker_class <= (index_dt_&index_class + &PSSA_before_after_1); run; /* PROC MEANS to count total number of new users of both INDEX DRUG and MARKER DRUG within prespecified PSSA window */ proc means data=&index_class._&marker_class.window n; var enrolid; title "New Users of Both &index_class and &marker_class - NOT excluding same day use"; run; /* As suggested by Jesper Hallas, excluding individuals who started INDEX DRUG and MARKER DRUG on the same day */ data &library..&index_class._&marker_class._no_same_day; set &index_class._&marker_class.window; where index_dt_&index_class ne index_dt_&marker_class; run; /* PROC MEANS to count total number of new users of both INDEX DRUG and MARKER DRUG within prespecified PSSA window, excluding those who started drugs both on the same day */ proc means data=&library..&index_class._&marker_class._no_same_day n; var enrolid; title "New Users of Both &index_class and &marker_class - excluding same day use"; run; /********************************/ /* Main Analysis */ data &index_class._&marker_class._main (keep=enrolid index_dt_&index_class index_dt_&marker_class &index_class._days &marker_class._days); set &library..&index_class._&marker_class._no_same_day; &index_class._days = index_dt_&index_class - 0; &marker_class._days = index_dt_&marker_class - 0; run; /********************************/ /* Age Subgroups */ data &index_class._&marker_class._1849 (keep=enrolid index_dt_&index_class index_dt_&marker_class &index_class._days &marker_class._days); set &library..&index_class._&marker_class._no_same_day; where year(index_dt_&index_class)-dobyr >= 20 and year(index_dt_&index_class)-dobyr < 52; &index_class._days = index_dt_&index_class - 0; &marker_class._days = index_dt_&marker_class - 0; run; data &index_class._&marker_class._5064 (keep=enrolid index_dt_&index_class index_dt_&marker_class &index_class._days &marker_class._days); set &library..&index_class._&marker_class._no_same_day; where year(index_dt_&index_class)-dobyr >= 52 and year(index_dt_&index_class)-dobyr < 67; &index_class._days = index_dt_&index_class - 0; &marker_class._days = index_dt_&marker_class - 0; run; data &index_class._&marker_class._lt65 (keep=enrolid index_dt_&index_class index_dt_&marker_class &index_class._days &marker_class._days); set &library..&index_class._&marker_class._no_same_day; where year(index_dt_&index_class)-dobyr >= 20 and year(index_dt_&index_class)-dobyr < 67; &index_class._days = index_dt_&index_class - 0; &marker_class._days = index_dt_&marker_class - 0; run; data &index_class._&marker_class._ge65 (keep=enrolid index_dt_&index_class index_dt_&marker_class &index_class._days &marker_class._days); set &library..&index_class._&marker_class._no_same_day; where year(index_dt_&index_class)-dobyr >= 67; &index_class._days = index_dt_&index_class - 0; &marker_class._days = index_dt_&marker_class - 0; run; /********************************/ /* Gender Subgroups */ data &index_class._&marker_class._male (keep=enrolid index_dt_&index_class index_dt_&marker_class &index_class._days &marker_class._days); set &library..&index_class._&marker_class._no_same_day; where SEX = '1'; &index_class._days = index_dt_&index_class - 0; &marker_class._days = index_dt_&marker_class - 0; run; data &index_class._&marker_class._female (keep=enrolid index_dt_&index_class index_dt_&marker_class &index_class._days &marker_class._days); set &library..&index_class._&marker_class._no_same_day; where SEX = '2'; &index_class._days = index_dt_&index_class - 0; &marker_class._days = index_dt_&marker_class - 0; run; /********************************/ /* Comorbidity Subgroups */ %if &comorbid_1_yn = Y %then %do; data &index_class._&marker_class._com1 (keep=enrolid index_dt_&index_class index_dt_&marker_class &index_class._days &marker_class._days); set &library..&index_class._&marker_class._no_same_day; where com_diag_1 = 1; &index_class._days = index_dt_&index_class - 0; &marker_class._days = index_dt_&marker_class - 0; run; data &index_class._&marker_class._no_com1 (keep=enrolid index_dt_&index_class index_dt_&marker_class &index_class._days &marker_class._days); set &library..&index_class._&marker_class._no_same_day; where com_diag_1 ne 1; &index_class._days = index_dt_&index_class - 0; &marker_class._days = index_dt_&marker_class - 0; run; %end; %if &comorbid_2_yn = Y %then %do; data &index_class._&marker_class._com2 (keep=enrolid index_dt_&index_class index_dt_&marker_class &index_class._days &marker_class._days); set &library..&index_class._&marker_class._no_same_day; where com_diag_2 = 1; &index_class._days = index_dt_&index_class - 0; &marker_class._days = index_dt_&marker_class - 0; run; data &index_class._&marker_class._no_com2 (keep=enrolid index_dt_&index_class index_dt_&marker_class &index_class._days &marker_class._days); set &library..&index_class._&marker_class._no_same_day; where com_diag_2 ne 1; &index_class._days = index_dt_&index_class - 0; &marker_class._days = index_dt_&marker_class - 0; run; %end; %if &comorbid_3_yn = Y %then %do; data &index_class._&marker_class._com3 (keep=enrolid index_dt_&index_class index_dt_&marker_class &index_class._days &marker_class._days); set &library..&index_class._&marker_class._no_same_day; where com_diag_3 = 1; &index_class._days = index_dt_&index_class - 0; &marker_class._days = index_dt_&marker_class - 0; run; data &index_class._&marker_class._no_com3 (keep=enrolid index_dt_&index_class index_dt_&marker_class &index_class._days &marker_class._days); set &library..&index_class._&marker_class._no_same_day; where com_diag_3 ne 1; &index_class._days = index_dt_&index_class - 0; &marker_class._days = index_dt_&marker_class - 0; run; %end; /********************************/ /* Individual Index Drug Subgroups */ %do i=1 %to %sysfunc(countw(&index_drugs)); %let index_drug_scan = %scan(&index_drugs, &i); data &index_class._&marker_class._idrug_&i; set &library..&index_class._&marker_class._no_same_day; where index(upcase(&index_class),"&index_drug_scan") >0; &index_class._days = index_dt_&index_class - 0; &marker_class._days = index_dt_&marker_class - 0; run; %end; /********************************/ /* Year Subgroups */ data &index_class._&marker_class._yr_1 (keep=enrolid index_dt_&index_class index_dt_&marker_class &index_class._days &marker_class._days); set &library..&index_class._&marker_class._no_same_day; where year(index_dt_&index_class) >= &year_1 and year(index_dt_&index_class) < &year_2; &index_class._days = index_dt_&index_class - 0; &marker_class._days = index_dt_&marker_class - 0; run; data &index_class._&marker_class._yr_2 (keep=enrolid index_dt_&index_class index_dt_&marker_class &index_class._days &marker_class._days); set &library..&index_class._&marker_class._no_same_day; where year(index_dt_&index_class) >= &year_2 and year(index_dt_&index_class) < &year_3; &index_class._days = index_dt_&index_class - 0; &marker_class._days = index_dt_&marker_class - 0; run; data &index_class._&marker_class._yr_3 (keep=enrolid index_dt_&index_class index_dt_&marker_class &index_class._days &marker_class._days); set &library..&index_class._&marker_class._no_same_day; where year(index_dt_&index_class) >= &year_3 and year(index_dt_&index_class) < &year_4; &index_class._days = index_dt_&index_class - 0; &marker_class._days = index_dt_&marker_class - 0; run; /*****************************************************************************************************/ /* Combining NEGATIVE CONTROL/MARKER Drug use */ /* Left joining to identify individuals who initiated NEGATIVE CONTROL DRUG and MARKER DRUG */ proc sql; create table combine_&neg_control_class._&marker_class as select a.*, b.&marker_class, b.index_dt_&marker_class from &library..&neg_control_class._exc_age a left join &library..continuous_&marker_class b on a.enrolid=b.enrolid; quit; /* Including only individuals that initiated NEGATIVE CONTROL DRUG and MARKER DRUG within the prespecified PSSA window */ data &neg_control_class._&marker_class.window; set combine_&neg_control_class._&marker_class; where (index_dt_&neg_control_class - &PSSA_before_after_1) <= index_dt_&marker_class <= (index_dt_&neg_control_class + &PSSA_before_after_1); run; /* PROC MEANS to count total number of new users of both NEGATIVE CONTROL DRUG and MARKER DRUG within prespecified PSSA window */ proc means data=&neg_control_class._&marker_class.window n; var enrolid; title "New Users of Both &neg_control_class and &marker_class - NOT excluding same day use"; run; /* As suggested by Jesper Hallas, excluding individuals who started NEGATIVE CONTROL DRUG and MARKER DRUG on the same day */ data &neg_control_class._&marker_class._no_same_day; set &neg_control_class._&marker_class.window; where index_dt_&neg_control_class ne index_dt_&marker_class; run; /* PROC MEANS to count total number of new users of both INDEX DRUG and MARKER DRUG within prespecified PSSA window, excluding those who started drugs both on the same day */ proc means data=&neg_control_class._&marker_class._no_same_day n; var enrolid; title "New Users of Both &neg_control_class and &marker_class - excluding same day use"; run; /* Left joining NEGATIVE CONTROL/MARKER DRUG new users to INDEX DRUG new users */ proc sql; create table &neg_control_class._wo_&index_class._pat as select a.*, b.index_dt_&index_class from &neg_control_class._&marker_class._no_same_day a left join &library..continuous_&index_class b on a.enrolid=b.enrolid; quit; /* Flagging individuals who filled INDEX DRUG within the prespecified PSSA time window before or after NEGATIVE CONTROL new use */ data &neg_control_class._wo_&index_class._pat_2; set &neg_control_class._wo_&index_class._pat; exclude_drug = 0; if (index_dt_&index_class - &PSSA_before_after_1)= 20 and year(index_dt_&neg_control_class)-dobyr < 52; &neg_control_class._days = index_dt_&neg_control_class - 0; &marker_class._days = index_dt_&marker_class - 0; run; data &neg_control_class._&marker_class._5064 (keep=enrolid index_dt_&neg_control_class index_dt_&marker_class &neg_control_class._days &marker_class._days); set &library..negative_&neg_control_class; where year(index_dt_&neg_control_class)-dobyr >= 52 and year(index_dt_&neg_control_class)-dobyr < 67; &neg_control_class._days = index_dt_&neg_control_class - 0; &marker_class._days = index_dt_&marker_class - 0; run; data &neg_control_class._&marker_class._lt65 (keep=enrolid index_dt_&neg_control_class index_dt_&marker_class &neg_control_class._days &marker_class._days); set &library..negative_&neg_control_class; where year(index_dt_&neg_control_class)-dobyr >= 20 and year(index_dt_&neg_control_class)-dobyr < 67; &neg_control_class._days = index_dt_&neg_control_class - 0; &marker_class._days = index_dt_&marker_class - 0; run; data &neg_control_class._&marker_class._ge65 (keep=enrolid index_dt_&neg_control_class index_dt_&marker_class &neg_control_class._days &marker_class._days); set &library..negative_&neg_control_class; where year(index_dt_&neg_control_class)-dobyr >= 67; &neg_control_class._days = index_dt_&neg_control_class - 0; &marker_class._days = index_dt_&marker_class - 0; run; /********************************/ /* Gender Subgroups - Negative Control */ data &neg_control_class._&marker_class._male (keep=enrolid index_dt_&neg_control_class index_dt_&marker_class &neg_control_class._days &marker_class._days); set &library..negative_&neg_control_class; where SEX = '1'; &neg_control_class._days = index_dt_&neg_control_class - 0; &marker_class._days = index_dt_&marker_class - 0; run; data &neg_control_class._&marker_class._female (keep=enrolid index_dt_&neg_control_class index_dt_&marker_class &neg_control_class._days &marker_class._days); set &library..negative_&neg_control_class; where SEX = '2'; &neg_control_class._days = index_dt_&neg_control_class - 0; &marker_class._days = index_dt_&marker_class - 0; run; /********************************/ /* Comorbidity Subgroups - Negative Control */ %if &comorbid_1_yn = Y %then %do; data &neg_control_class._&marker_class._com1 (keep=enrolid index_dt_&neg_control_class index_dt_&marker_class &neg_control_class._days &marker_class._days); set &library..negative_&neg_control_class; where com_diag_1 = 1; &neg_control_class._days = index_dt_&neg_control_class - 0; &marker_class._days = index_dt_&marker_class - 0; run; data &neg_control_class._&marker_class._no_com1 (keep=enrolid index_dt_&neg_control_class index_dt_&marker_class &neg_control_class._days &marker_class._days); set &library..negative_&neg_control_class; where com_diag_1 ne 1; &neg_control_class._days = index_dt_&neg_control_class - 0; &marker_class._days = index_dt_&marker_class - 0; run; %end; %if &comorbid_2_yn = Y %then %do; data &neg_control_class._&marker_class._com2 (keep=enrolid index_dt_&neg_control_class index_dt_&marker_class &neg_control_class._days &marker_class._days); set &library..negative_&neg_control_class; where com_diag_2 = 1; &neg_control_class._days = index_dt_&neg_control_class - 0; &marker_class._days = index_dt_&marker_class - 0; run; data &neg_control_class._&marker_class._no_com2 (keep=enrolid index_dt_&neg_control_class index_dt_&marker_class &neg_control_class._days &marker_class._days); set &library..negative_&neg_control_class; where com_diag_2 ne 1; &neg_control_class._days = index_dt_&neg_control_class - 0; &marker_class._days = index_dt_&marker_class - 0; run; %end; %if &comorbid_3_yn = Y %then %do; data &neg_control_class._&marker_class._com3 (keep=enrolid index_dt_&neg_control_class index_dt_&marker_class &neg_control_class._days &marker_class._days); set &library..negative_&neg_control_class; where com_diag_3 = 1; &neg_control_class._days = index_dt_&neg_control_class - 0; &marker_class._days = index_dt_&marker_class - 0; run; data &neg_control_class._&marker_class._no_com3 (keep=enrolid index_dt_&neg_control_class index_dt_&marker_class &neg_control_class._days &marker_class._days); set &library..negative_&neg_control_class; where com_diag_3 ne 1; &neg_control_class._days = index_dt_&neg_control_class - 0; &marker_class._days = index_dt_&marker_class - 0; run; %end; /********************************/ /* Year Subgroups - Negative Control */ data &neg_control_class._&marker_class._yr_1 (keep=enrolid index_dt_&neg_control_class index_dt_&marker_class &neg_control_class._days &marker_class._days); set &library..negative_&neg_control_class; where year(index_dt_&neg_control_class) >= &year_1 and year(index_dt_&neg_control_class) < &year_2; &neg_control_class._days = index_dt_&neg_control_class - 0; &marker_class._days = index_dt_&marker_class - 0; run; data &neg_control_class._&marker_class._yr_2 (keep=enrolid index_dt_&neg_control_class index_dt_&marker_class &neg_control_class._days &marker_class._days); set &library..negative_&neg_control_class; where year(index_dt_&neg_control_class) >= &year_2 and year(index_dt_&neg_control_class) < &year_3; &neg_control_class._days = index_dt_&neg_control_class - 0; &marker_class._days = index_dt_&marker_class - 0; run; data &neg_control_class._&marker_class._yr_3 (keep=enrolid index_dt_&neg_control_class index_dt_&marker_class &neg_control_class._days &marker_class._days); set &library..negative_&neg_control_class; where year(index_dt_&neg_control_class) >= &year_3 and year(index_dt_&neg_control_class) < &year_4; &neg_control_class._days = index_dt_&neg_control_class - 0; &marker_class._days = index_dt_&marker_class - 0; run; /*****************************************************************************************************/ /*****************************************************************************************************/ /*****************************************************************************************************/ /*****************************************************************************************************/ /*****************************************************************************************************/ /*****************************************************************************************************/ /*****************************************************************************************************/ /*****************************************************************************************************/ /*****************************************************************************************************/ /*****************************************************************************************************/ /*****************************************************************************************************/ /*****************************************************************************************************/ /* INDEX DRUG */ /*****************************************************************************************************/ /*****************************************************************************************************/ /*****************************************************************************************************/ /*****************************************************************************************************/ /* PSSA Calculation - Main Analysis */ %if &PSSA_before_after_1 > 0 %then %do; %do i=1 %to %sysfunc(countw(&subgrp)); %let subgrps = %scan(&subgrp, &i); data &index_class._&marker_class._&subgrps._&PSSA_before_after_1; set &index_class._&marker_class._&subgrps; flag=1; DIF = &marker_class._days - &index_class._days; INDEX_then_MARKER = (&index_class._days=<&marker_class._days); run; proc sort data=&index_class._&marker_class._&subgrps._&PSSA_before_after_1 nodupkey; by _all_; run; data &index_class._&marker_class._&subgrps._&PSSA_before_after_1.a; set &index_class._&marker_class._&subgrps._&PSSA_before_after_1; if -(&PSSA_before_after_1)<=DIF=<(&PSSA_before_after_1) then output; run; proc means data=&index_class._&marker_class._&subgrps._&PSSA_before_after_1.a n sum noprint; var INDEX_then_MARKER; output out=&index_class._&marker_class._&subgrps._&PSSA_before_after_1.b n=TOTAL sum=INDEX_then_MARKER; run; data &index_class._&marker_class._&subgrps._&PSSA_before_after_1.c (keep=indexdrug&min_days-indexdrug&max_days markerdrug&min_days-markerdrug&max_days s_index s_marker s_upper s_lower flag); set &index_class._&marker_class._&subgrps._&PSSA_before_after_1; by flag; array indexdrug(*) indexdrug1-indexdrug&max_days; array markerdrug(*) markerdrug1-markerdrug&max_days; retain indexdrug1-indexdrug&max_days markerdrug1-markerdrug&max_days; if first.flag then do; do i=1 to &max_days; indexdrug(i)=0; markerdrug(i)=0; end; end; if &index_class._days<(&max_days+1) then indexdrug(&index_class._days)=indexdrug(&index_class._days)+1; if &marker_class._days<(&max_days+1) then markerdrug(&marker_class._days)=markerdrug(&marker_class._days)+1; if last.flag then do; s_index=0; do i=1 to &max_days; s_index=s_index+indexdrug(i); end; s_marker=0; do j=1 to &max_days; s_marker=s_marker+markerdrug(j); end; s_upper=0; do i=&min_days to (&max_days - 1); js= i+1; do j=js to &max_days; if 0=0 & MARKER_then_INDEX >0 then r_c=log(INDEX_then_MARKER/MARKER_then_INDEX); else r_c=.; if INDEX_then_MARKER =0 or MARKER_then_INDEX =0 then std_r_c=.; else std_r_c=sqrt((1/INDEX_then_MARKER)+(1/MARKER_then_INDEX)); expcsr = exp(r_c); null_e=(s_upper)/s_lower; if expcsr>=0 & null_e >0 then ASR=expcsr/null_e; else ASR=.; estimate=log(ASR); if &CI=90 then do; ll=estimate-1.64*std_r_c; ul=estimate+1.64*std_r_c; end; if &CI=95 then do; ll=estimate-1.96*std_r_c; ul=estimate+1.96*std_r_c; end; if &CI=99 then do; ll=estimate-2.58*std_r_c; ul=estimate+2.58*std_r_c; end; if &CI=99.9 then do; ll=estimate-3.29*std_r_c; ul=estimate+3.29*std_r_c; end; ASR_ll=exp(ll); ASR_ul=exp(ul); run; data &index_class._&marker_class._&subgrps._&PSSA_before_after_1.e (keep= csr nsr estimate sterr ll ul ASR ASR_ll ASR_ul); set &index_class._&marker_class._&subgrps._&PSSA_before_after_1.d; csr=expcsr; nsr=null_e; sterr=std_r_c; run; proc means data=&index_class._&marker_class._&subgrps._&PSSA_before_after_1.d sum; var INDEX_then_MARKER MARKER_then_INDEX; title "Number of Individuals with &index_class then &marker_class ; &marker_class then &index_class - Analysis: &subgrps - &PSSA_before_after_1 Day Window"; run; proc means data=&index_class._&marker_class._&subgrps n; var enrolid; title "Total Number of Individuals included in &index_class -> &marker_class PSSA - Analysis: &subgrps - &PSSA_before_after_1 Day Window"; run; proc means data=&index_class._&marker_class._&subgrps._&PSSA_before_after_1.e mean; var csr nsr ASR ASR_ll ASR_ul; title "CSR, NSR, ASR (CI) for &index_class -> &marker_class PSSA - Analysis: &subgrps - &PSSA_before_after_1 Day Window"; run; %end; %end; /*****************************************************************************************************/ /* PSSA Calculation - Time Window 2 */ %if &PSSA_before_after_2 > 0 %then %do; %do i=1 %to %sysfunc(countw(&subgrp)); %let subgrps = %scan(&subgrp, &i); data &index_class._&marker_class._&subgrps._&PSSA_before_after_2; set &index_class._&marker_class._&subgrps; flag=1; DIF = &marker_class._days - &index_class._days; INDEX_then_MARKER = (&index_class._days=<&marker_class._days); run; proc sort data=&index_class._&marker_class._&subgrps._&PSSA_before_after_2 nodupkey; by _all_; run; data &index_class._&marker_class._&subgrps._&PSSA_before_after_2.a; set &index_class._&marker_class._&subgrps._&PSSA_before_after_2; if -(&PSSA_before_after_2)<=DIF=<(&PSSA_before_after_2) then output; run; proc means data=&index_class._&marker_class._&subgrps._&PSSA_before_after_2.a n sum noprint; var INDEX_then_MARKER; output out=&index_class._&marker_class._&subgrps._&PSSA_before_after_2.b n=TOTAL sum=INDEX_then_MARKER; run; data &index_class._&marker_class._&subgrps._&PSSA_before_after_2.c (keep=indexdrug&min_days-indexdrug&max_days markerdrug&min_days-markerdrug&max_days s_index s_marker s_upper s_lower flag); set &index_class._&marker_class._&subgrps._&PSSA_before_after_2; by flag; array indexdrug(*) indexdrug1-indexdrug&max_days; array markerdrug(*) markerdrug1-markerdrug&max_days; retain indexdrug1-indexdrug&max_days markerdrug1-markerdrug&max_days; if first.flag then do; do i=1 to &max_days; indexdrug(i)=0; markerdrug(i)=0; end; end; if &index_class._days<(&max_days+1) then indexdrug(&index_class._days)=indexdrug(&index_class._days)+1; if &marker_class._days<(&max_days+1) then markerdrug(&marker_class._days)=markerdrug(&marker_class._days)+1; if last.flag then do; s_index=0; do i=1 to &max_days; s_index=s_index+indexdrug(i); end; s_marker=0; do j=1 to &max_days; s_marker=s_marker+markerdrug(j); end; s_upper=0; do i=&min_days to (&max_days - 1); js= i+1; do j=js to &max_days; if 0=0 & MARKER_then_INDEX >0 then r_c=log(INDEX_then_MARKER/MARKER_then_INDEX); else r_c=.; if INDEX_then_MARKER =0 or MARKER_then_INDEX =0 then std_r_c=.; else std_r_c=sqrt((1/INDEX_then_MARKER)+(1/MARKER_then_INDEX)); expcsr = exp(r_c); null_e=(s_upper)/s_lower; if expcsr>=0 & null_e >0 then ASR=expcsr/null_e; else ASR=.; estimate=log(ASR); if &CI=90 then do; ll=estimate-1.64*std_r_c; ul=estimate+1.64*std_r_c; end; if &CI=95 then do; ll=estimate-1.96*std_r_c; ul=estimate+1.96*std_r_c; end; if &CI=99 then do; ll=estimate-2.58*std_r_c; ul=estimate+2.58*std_r_c; end; if &CI=99.9 then do; ll=estimate-3.29*std_r_c; ul=estimate+3.29*std_r_c; end; ASR_ll=exp(ll); ASR_ul=exp(ul); run; data &index_class._&marker_class._&subgrps._&PSSA_before_after_2.e (keep= csr nsr estimate sterr ll ul ASR ASR_ll ASR_ul); set &index_class._&marker_class._&subgrps._&PSSA_before_after_2.d; csr=expcsr; nsr=null_e; sterr=std_r_c; run; proc means data=&index_class._&marker_class._&subgrps._&PSSA_before_after_2.d sum; var INDEX_then_MARKER MARKER_then_INDEX; title "Number of Individuals with &index_class then &marker_class ; &marker_class then &index_class - Analysis: &subgrps - &PSSA_before_after_2 Day Window"; run; proc means data=&index_class._&marker_class._&subgrps n; var enrolid; title "Total Number of Individuals included in &index_class -> &marker_class PSSA - Analysis: &subgrps - &PSSA_before_after_2 Day Window"; run; proc means data=&index_class._&marker_class._&subgrps._&PSSA_before_after_2.e mean; var csr nsr ASR ASR_ll ASR_ul; title "CSR, NSR, ASR (CI) for &index_class -> &marker_class PSSA - Analysis: &subgrps - &PSSA_before_after_2 Day Window"; run; %end; %end; /* PSSA Calculation - Time Window 3 */ %if &PSSA_before_after_3 > 0 %then %do; %do i=1 %to %sysfunc(countw(&subgrp)); %let subgrps = %scan(&subgrp, &i); data &index_class._&marker_class._&subgrps._&PSSA_before_after_3; set &index_class._&marker_class._&subgrps; flag=1; DIF = &marker_class._days - &index_class._days; INDEX_then_MARKER = (&index_class._days=<&marker_class._days); run; proc sort data=&index_class._&marker_class._&subgrps._&PSSA_before_after_3 nodupkey; by _all_; run; data &index_class._&marker_class._&subgrps._&PSSA_before_after_3.a; set &index_class._&marker_class._&subgrps._&PSSA_before_after_3; if -(&PSSA_before_after_3)<=DIF=<(&PSSA_before_after_3) then output; run; proc means data=&index_class._&marker_class._&subgrps._&PSSA_before_after_3.a n sum noprint; var INDEX_then_MARKER; output out=&index_class._&marker_class._&subgrps._&PSSA_before_after_3.b n=TOTAL sum=INDEX_then_MARKER; run; data &index_class._&marker_class._&subgrps._&PSSA_before_after_3.c (keep=indexdrug&min_days-indexdrug&max_days markerdrug&min_days-markerdrug&max_days s_index s_marker s_upper s_lower flag); set &index_class._&marker_class._&subgrps._&PSSA_before_after_3; by flag; array indexdrug(*) indexdrug1-indexdrug&max_days; array markerdrug(*) markerdrug1-markerdrug&max_days; retain indexdrug1-indexdrug&max_days markerdrug1-markerdrug&max_days; if first.flag then do; do i=1 to &max_days; indexdrug(i)=0; markerdrug(i)=0; end; end; if &index_class._days<(&max_days+1) then indexdrug(&index_class._days)=indexdrug(&index_class._days)+1; if &marker_class._days<(&max_days+1) then markerdrug(&marker_class._days)=markerdrug(&marker_class._days)+1; if last.flag then do; s_index=0; do i=1 to &max_days; s_index=s_index+indexdrug(i); end; s_marker=0; do j=1 to &max_days; s_marker=s_marker+markerdrug(j); end; s_upper=0; do i=&min_days to (&max_days - 1); js= i+1; do j=js to &max_days; if 0=0 & MARKER_then_INDEX >0 then r_c=log(INDEX_then_MARKER/MARKER_then_INDEX); else r_c=.; if INDEX_then_MARKER =0 or MARKER_then_INDEX =0 then std_r_c=.; else std_r_c=sqrt((1/INDEX_then_MARKER)+(1/MARKER_then_INDEX)); expcsr = exp(r_c); null_e=(s_upper)/s_lower; if expcsr>=0 & null_e >0 then ASR=expcsr/null_e; else ASR=.; estimate=log(ASR); if &CI=90 then do; ll=estimate-1.64*std_r_c; ul=estimate+1.64*std_r_c; end; if &CI=95 then do; ll=estimate-1.96*std_r_c; ul=estimate+1.96*std_r_c; end; if &CI=99 then do; ll=estimate-2.58*std_r_c; ul=estimate+2.58*std_r_c; end; if &CI=99.9 then do; ll=estimate-3.29*std_r_c; ul=estimate+3.29*std_r_c; end; ASR_ll=exp(ll); ASR_ul=exp(ul); run; data &index_class._&marker_class._&subgrps._&PSSA_before_after_3.e (keep= csr nsr estimate sterr ll ul ASR ASR_ll ASR_ul); set &index_class._&marker_class._&subgrps._&PSSA_before_after_3.d; csr=expcsr; nsr=null_e; sterr=std_r_c; run; proc means data=&index_class._&marker_class._&subgrps._&PSSA_before_after_3.d sum; var INDEX_then_MARKER MARKER_then_INDEX; title "Number of Individuals with &index_class then &marker_class ; &marker_class then &index_class - Analysis: &subgrps - &PSSA_before_after_3 Day Window"; run; proc means data=&index_class._&marker_class._&subgrps n; var enrolid; title "Total Number of Individuals included in &index_class -> &marker_class PSSA - Analysis: &subgrps - &PSSA_before_after_3 Day Window"; run; proc means data=&index_class._&marker_class._&subgrps._&PSSA_before_after_3.e mean; var csr nsr ASR ASR_ll ASR_ul; title "CSR, NSR, ASR (CI) for &index_class -> &marker_class PSSA - Analysis: &subgrps - &PSSA_before_after_3 Day Window"; run; %end; %end; /********************************/ /* PSSA Calculation - Individual Index Drugs */ %do i=1 %to %sysfunc(countw(&index_drugs)); %let index_drug_scan = %scan(&index_drugs, &i); data &index_class._&marker_class._idrug_&i._2; set &index_class._&marker_class._idrug_&i; flag=1; DIF = &marker_class._days - &index_class._days; INDEX_then_MARKER = (&index_class._days=<&marker_class._days); run; proc sort data=&index_class._&marker_class._idrug_&i._2 nodupkey; by _all_; run; data &index_class._&marker_class._idrug_&i._merge_1; set &index_class._&marker_class._idrug_&i._2; if -(&PSSA_before_after_1)<=DIF=<(&PSSA_before_after_1) then output; run; proc means data=&index_class._&marker_class._idrug_&i._merge_1 n sum noprint; var INDEX_then_MARKER; output out=&index_class._&marker_class._idrug_&i._merge_2 n=TOTAL sum=INDEX_then_MARKER; run; data &index_class._&marker_class._idrug_&i._merge_3 (keep=indexdrug&min_days-indexdrug&max_days markerdrug&min_days-markerdrug&max_days s_index s_marker s_upper s_lower flag); set &index_class._&marker_class._idrug_&i._2; by flag; array indexdrug(*) indexdrug1-indexdrug&max_days; array markerdrug(*) markerdrug1-markerdrug&max_days; retain indexdrug1-indexdrug&max_days markerdrug1-markerdrug&max_days; if first.flag then do; do i=1 to &max_days; indexdrug(i)=0; markerdrug(i)=0; end; end; if &index_class._days<(&max_days+1) then indexdrug(&index_class._days)=indexdrug(&index_class._days)+1; if &marker_class._days<(&max_days+1) then markerdrug(&marker_class._days)=markerdrug(&marker_class._days)+1; if last.flag then do; s_index=0; do i=1 to &max_days; s_index=s_index+indexdrug(i); end; s_marker=0; do j=1 to &max_days; s_marker=s_marker+markerdrug(j); end; s_upper=0; do i=&min_days to (&max_days - 1); js= i+1; do j=js to &max_days; if 0=0 & MARKER_then_INDEX >0 then r_c=log(INDEX_then_MARKER/MARKER_then_INDEX); else r_c=.; if INDEX_then_MARKER =0 or MARKER_then_INDEX =0 then std_r_c=.; else std_r_c=sqrt((1/INDEX_then_MARKER)+(1/MARKER_then_INDEX)); expcsr = exp(r_c); null_e=(s_upper)/s_lower; if expcsr>=0 & null_e >0 then ASR=expcsr/null_e; else ASR=.; estimate=log(ASR); if &CI=90 then do; ll=estimate-1.64*std_r_c; ul=estimate+1.64*std_r_c; end; if &CI=95 then do; ll=estimate-1.96*std_r_c; ul=estimate+1.96*std_r_c; end; if &CI=99 then do; ll=estimate-2.58*std_r_c; ul=estimate+2.58*std_r_c; end; if &CI=99.9 then do; ll=estimate-3.29*std_r_c; ul=estimate+3.29*std_r_c; end; ASR_ll=exp(ll); ASR_ul=exp(ul); run; data &index_class._&marker_class._idrug_&i._final (keep= csr nsr estimate sterr ll ul ASR ASR_ll ASR_ul); set &index_class._&marker_class._idrug_&i._merge_4; csr=expcsr; nsr=null_e; sterr=std_r_c; run; proc means data=&index_class._&marker_class._idrug_&i._merge_4 sum; var INDEX_then_MARKER MARKER_then_INDEX; title "Number of Individuals with &index_drug_scan then &marker_class ; &marker_class then &index_drug_scan - &PSSA_before_after_1 Day Window"; run; proc means data=&index_class._&marker_class._idrug_&i n; var enrolid; title "Total Number of Individuals included in &index_drug_scan -> &marker_class PSSA - &PSSA_before_after_1 Day Window"; run; proc means data=&index_class._&marker_class._idrug_&i._final mean; var csr nsr ASR ASR_ll ASR_ul; title "CSR, NSR, ASR (CI) for &index_drug_scan -> &marker_class PSSA - &PSSA_before_after_1 Day Window"; run; %end; /*****************************************************************************************************/ /*****************************************************************************************************/ /*****************************************************************************************************/ /*****************************************************************************************************/ /*****************************************************************************************************/ /*****************************************************************************************************/ /*****************************************************************************************************/ /*****************************************************************************************************/ /*****************************************************************************************************/ /*****************************************************************************************************/ /*****************************************************************************************************/ /*****************************************************************************************************/ /* NEGATIVE CONTROL DRUG */ /*****************************************************************************************************/ /*****************************************************************************************************/ /*****************************************************************************************************/ /*****************************************************************************************************/ /* PSSA Calculation */ %if &PSSA_before_after_1 > 0 %then %do; %do i=1 %to %sysfunc(countw(&subgrp)); %let subgrps = %scan(&subgrp, &i); data &neg_control_class._&marker_class._&subgrps._&PSSA_before_after_1; set &neg_control_class._&marker_class._&subgrps; flag=1; DIF = &marker_class._days - &neg_control_class._days; INDEX_then_MARKER = (&neg_control_class._days=<&marker_class._days); run; proc sort data=&neg_control_class._&marker_class._&subgrps._&PSSA_before_after_1 nodupkey; by _all_; run; data &neg_control_class._&marker_class._&subgrps._&PSSA_before_after_1.a; set &neg_control_class._&marker_class._&subgrps._&PSSA_before_after_1; if -(&PSSA_before_after_1)<=DIF=<(&PSSA_before_after_1) then output; run; proc means data=&neg_control_class._&marker_class._&subgrps._&PSSA_before_after_1.a n sum noprint; var INDEX_then_MARKER; output out=&neg_control_class._&marker_class._&subgrps._&PSSA_before_after_1.b n=TOTAL sum=INDEX_then_MARKER; run; data &neg_control_class._&marker_class._&subgrps._&PSSA_before_after_1.c (keep=indexdrug&min_days-indexdrug&max_days markerdrug&min_days-markerdrug&max_days s_index s_marker s_upper s_lower flag); set &neg_control_class._&marker_class._&subgrps._&PSSA_before_after_1; by flag; array indexdrug(*) indexdrug1-indexdrug&max_days; array markerdrug(*) markerdrug1-markerdrug&max_days; retain indexdrug1-indexdrug&max_days markerdrug1-markerdrug&max_days; if first.flag then do; do i=1 to &max_days; indexdrug(i)=0; markerdrug(i)=0; end; end; if &neg_control_class._days<(&max_days+1) then indexdrug(&neg_control_class._days)=indexdrug(&neg_control_class._days)+1; if &marker_class._days<(&max_days+1) then markerdrug(&marker_class._days)=markerdrug(&marker_class._days)+1; if last.flag then do; s_index=0; do i=1 to &max_days; s_index=s_index+indexdrug(i); end; s_marker=0; do j=1 to &max_days; s_marker=s_marker+markerdrug(j); end; s_upper=0; do i=&min_days to (&max_days - 1); js= i+1; do j=js to &max_days; if 0=0 & MARKER_then_INDEX >0 then r_c=log(INDEX_then_MARKER/MARKER_then_INDEX); else r_c=.; if INDEX_then_MARKER =0 or MARKER_then_INDEX =0 then std_r_c=.; else std_r_c=sqrt((1/INDEX_then_MARKER)+(1/MARKER_then_INDEX)); expcsr = exp(r_c); null_e=(s_upper)/s_lower; if expcsr>=0 & null_e >0 then ASR=expcsr/null_e; else ASR=.; estimate=log(ASR); if &CI=90 then do; ll=estimate-1.64*std_r_c; ul=estimate+1.64*std_r_c; end; if &CI=95 then do; ll=estimate-1.96*std_r_c; ul=estimate+1.96*std_r_c; end; if &CI=99 then do; ll=estimate-2.58*std_r_c; ul=estimate+2.58*std_r_c; end; if &CI=99.9 then do; ll=estimate-3.29*std_r_c; ul=estimate+3.29*std_r_c; end; ASR_ll=exp(ll); ASR_ul=exp(ul); run; data &neg_control_class._&marker_class._&subgrps._&PSSA_before_after_1.e (keep= csr nsr estimate sterr ll ul ASR ASR_ll ASR_ul); set &neg_control_class._&marker_class._&subgrps._&PSSA_before_after_1.d; csr=expcsr; nsr=null_e; sterr=std_r_c; run; proc means data=&neg_control_class._&marker_class._&subgrps._&PSSA_before_after_1.d sum; var INDEX_then_MARKER MARKER_then_INDEX; title "Number of Individuals with &neg_control_class then &marker_class ; &marker_class then &neg_control_class - Analysis: &subgrps - &PSSA_before_after_1 Day Window"; run; proc means data=&neg_control_class._&marker_class._&subgrps n; var enrolid; title "Total Number of Individuals included in &neg_control_class -> &marker_class PSSA - Analysis: &subgrps - &PSSA_before_after_1 Day Window"; run; proc means data=&neg_control_class._&marker_class._&subgrps._&PSSA_before_after_1.e mean; var csr nsr ASR ASR_ll ASR_ul; title "CSR, NSR, ASR (CI) for &neg_control_class -> &marker_class PSSA - Analysis: &subgrps - &PSSA_before_after_1 Day Window"; run; %end; %end; /*****************************************************************************************************/ /* PSSA Calculation - Time Window 2 */ %if &PSSA_before_after_2 > 0 %then %do; %do i=1 %to %sysfunc(countw(&subgrp)); %let subgrps = %scan(&subgrp, &i); data &neg_control_class._&marker_class._&subgrps._&PSSA_before_after_2; set &neg_control_class._&marker_class._&subgrps; flag=1; DIF = &marker_class._days - &neg_control_class._days; INDEX_then_MARKER = (&neg_control_class._days=<&marker_class._days); run; proc sort data=&neg_control_class._&marker_class._&subgrps._&PSSA_before_after_2 nodupkey; by _all_; run; data &neg_control_class._&marker_class._&subgrps._&PSSA_before_after_2.a; set &neg_control_class._&marker_class._&subgrps._&PSSA_before_after_2; if -(&PSSA_before_after_2)<=DIF=<(&PSSA_before_after_2) then output; run; proc means data=&neg_control_class._&marker_class._&subgrps._&PSSA_before_after_2.a n sum noprint; var INDEX_then_MARKER; output out=&neg_control_class._&marker_class._&subgrps._&PSSA_before_after_2.b n=TOTAL sum=INDEX_then_MARKER; run; data &neg_control_class._&marker_class._&subgrps._&PSSA_before_after_2.c (keep=indexdrug&min_days-indexdrug&max_days markerdrug&min_days-markerdrug&max_days s_index s_marker s_upper s_lower flag); set &neg_control_class._&marker_class._&subgrps._&PSSA_before_after_2; by flag; array indexdrug(*) indexdrug1-indexdrug&max_days; array markerdrug(*) markerdrug1-markerdrug&max_days; retain indexdrug1-indexdrug&max_days markerdrug1-markerdrug&max_days; if first.flag then do; do i=1 to &max_days; indexdrug(i)=0; markerdrug(i)=0; end; end; if &neg_control_class._days<(&max_days+1) then indexdrug(&neg_control_class._days)=indexdrug(&neg_control_class._days)+1; if &marker_class._days<(&max_days+1) then markerdrug(&marker_class._days)=markerdrug(&marker_class._days)+1; if last.flag then do; s_index=0; do i=1 to &max_days; s_index=s_index+indexdrug(i); end; s_marker=0; do j=1 to &max_days; s_marker=s_marker+markerdrug(j); end; s_upper=0; do i=&min_days to (&max_days - 1); js= i+1; do j=js to &max_days; if 0=0 & MARKER_then_INDEX >0 then r_c=log(INDEX_then_MARKER/MARKER_then_INDEX); else r_c=.; if INDEX_then_MARKER =0 or MARKER_then_INDEX =0 then std_r_c=.; else std_r_c=sqrt((1/INDEX_then_MARKER)+(1/MARKER_then_INDEX)); expcsr = exp(r_c); null_e=(s_upper)/s_lower; if expcsr>=0 & null_e >0 then ASR=expcsr/null_e; else ASR=.; estimate=log(ASR); if &CI=90 then do; ll=estimate-1.64*std_r_c; ul=estimate+1.64*std_r_c; end; if &CI=95 then do; ll=estimate-1.96*std_r_c; ul=estimate+1.96*std_r_c; end; if &CI=99 then do; ll=estimate-2.58*std_r_c; ul=estimate+2.58*std_r_c; end; if &CI=99.9 then do; ll=estimate-3.29*std_r_c; ul=estimate+3.29*std_r_c; end; ASR_ll=exp(ll); ASR_ul=exp(ul); run; data &neg_control_class._&marker_class._&subgrps._&PSSA_before_after_2.e (keep= csr nsr estimate sterr ll ul ASR ASR_ll ASR_ul); set &neg_control_class._&marker_class._&subgrps._&PSSA_before_after_2.d; csr=expcsr; nsr=null_e; sterr=std_r_c; run; proc means data=&neg_control_class._&marker_class._&subgrps._&PSSA_before_after_2.d sum; var INDEX_then_MARKER MARKER_then_INDEX; title "Number of Individuals with &neg_control_class then &marker_class ; &marker_class then &neg_control_class - Analysis: &subgrps - &PSSA_before_after_2 Day Window"; run; proc means data=&neg_control_class._&marker_class._&subgrps n; var enrolid; title "Total Number of Individuals included in &neg_control_class -> &marker_class PSSA - Analysis: &subgrps - &PSSA_before_after_2 Day Window"; run; proc means data=&neg_control_class._&marker_class._&subgrps._&PSSA_before_after_2.e mean; var csr nsr ASR ASR_ll ASR_ul; title "CSR, NSR, ASR (CI) for &neg_control_class -> &marker_class PSSA - Analysis: &subgrps - &PSSA_before_after_2 Day Window"; run; %end; %end; /* PSSA Calculation - Time Window 3 */ %if &PSSA_before_after_3 > 0 %then %do; %do i=1 %to %sysfunc(countw(&subgrp)); %let subgrps = %scan(&subgrp, &i); data &neg_control_class._&marker_class._&subgrps._&PSSA_before_after_3; set &neg_control_class._&marker_class._&subgrps; flag=1; DIF = &marker_class._days - &neg_control_class._days; INDEX_then_MARKER = (&neg_control_class._days=<&marker_class._days); run; proc sort data=&neg_control_class._&marker_class._&subgrps._&PSSA_before_after_3 nodupkey; by _all_; run; data &neg_control_class._&marker_class._&subgrps._&PSSA_before_after_3.a; set &neg_control_class._&marker_class._&subgrps._&PSSA_before_after_3; if -(&PSSA_before_after_3)<=DIF=<(&PSSA_before_after_3) then output; run; proc means data=&neg_control_class._&marker_class._&subgrps._&PSSA_before_after_3.a n sum noprint; var INDEX_then_MARKER; output out=&neg_control_class._&marker_class._&subgrps._&PSSA_before_after_3.b n=TOTAL sum=INDEX_then_MARKER; run; data &neg_control_class._&marker_class._&subgrps._&PSSA_before_after_3.c (keep=indexdrug&min_days-indexdrug&max_days markerdrug&min_days-markerdrug&max_days s_index s_marker s_upper s_lower flag); set &neg_control_class._&marker_class._&subgrps._&PSSA_before_after_3; by flag; array indexdrug(*) indexdrug1-indexdrug&max_days; array markerdrug(*) markerdrug1-markerdrug&max_days; retain indexdrug1-indexdrug&max_days markerdrug1-markerdrug&max_days; if first.flag then do; do i=1 to &max_days; indexdrug(i)=0; markerdrug(i)=0; end; end; if &neg_control_class._days<(&max_days+1) then indexdrug(&neg_control_class._days)=indexdrug(&neg_control_class._days)+1; if &marker_class._days<(&max_days+1) then markerdrug(&marker_class._days)=markerdrug(&marker_class._days)+1; if last.flag then do; s_index=0; do i=1 to &max_days; s_index=s_index+indexdrug(i); end; s_marker=0; do j=1 to &max_days; s_marker=s_marker+markerdrug(j); end; s_upper=0; do i=&min_days to (&max_days - 1); js= i+1; do j=js to &max_days; if 0=0 & MARKER_then_INDEX >0 then r_c=log(INDEX_then_MARKER/MARKER_then_INDEX); else r_c=.; if INDEX_then_MARKER =0 or MARKER_then_INDEX =0 then std_r_c=.; else std_r_c=sqrt((1/INDEX_then_MARKER)+(1/MARKER_then_INDEX)); expcsr = exp(r_c); null_e=(s_upper)/s_lower; if expcsr>=0 & null_e >0 then ASR=expcsr/null_e; else ASR=.; estimate=log(ASR); if &CI=90 then do; ll=estimate-1.64*std_r_c; ul=estimate+1.64*std_r_c; end; if &CI=95 then do; ll=estimate-1.96*std_r_c; ul=estimate+1.96*std_r_c; end; if &CI=99 then do; ll=estimate-2.58*std_r_c; ul=estimate+2.58*std_r_c; end; if &CI=99.9 then do; ll=estimate-3.29*std_r_c; ul=estimate+3.29*std_r_c; end; ASR_ll=exp(ll); ASR_ul=exp(ul); run; data &neg_control_class._&marker_class._&subgrps._&PSSA_before_after_3.e (keep= csr nsr estimate sterr ll ul ASR ASR_ll ASR_ul); set &neg_control_class._&marker_class._&subgrps._&PSSA_before_after_3.d; csr=expcsr; nsr=null_e; sterr=std_r_c; run; proc means data=&neg_control_class._&marker_class._&subgrps._&PSSA_before_after_3.d sum; var INDEX_then_MARKER MARKER_then_INDEX; title "Number of Individuals with &neg_control_class then &marker_class ; &marker_class then &neg_control_class - Analysis: &subgrps - &PSSA_before_after_3 Day Window"; run; proc means data=&neg_control_class._&marker_class._&subgrps n; var enrolid; title "Total Number of Individuals included in &neg_control_class -> &marker_class PSSA - Analysis: &subgrps - &PSSA_before_after_3 Day Window"; run; proc means data=&neg_control_class._&marker_class._&subgrps._&PSSA_before_after_3.e mean; var csr nsr ASR ASR_ll ASR_ul; title "CSR, NSR, ASR (CI) for &neg_control_class -> &marker_class PSSA - Analysis: &subgrps - &PSSA_before_after_3 Day Window"; run; %end; %end; %mend PSSA; %PSSA(05_4 06_3 07_3 08_3 09_3 10_3, AMI, AMIODARONE, THY, THYROXINE, ROS, ROSUVASTATIN, main 1849 5064 lt65 ge65 male female yr_1 yr_2 yr_3);