Remove Voided Claims for Insurance Data Qiling Shi ABSTRACT The purpose of this study is to remove voided claims for insurance claim data using SAS. Suppose that for these voided claims, we don t have a flag to identify them at first. All we know is that they have the same absolute values with positive and negative amounts for the same insurance ID. A SAS macro with procedures such as PROC SQL and DATA STEPS is employed to do the data analysis. INTRODUCTION An insurance Claim is filed by a policyholder stating that an insured event has occurred and that the insurance company should provide coverage. An insurance adjuster could be set up with access to portions of the claim to just the right payment amount. Insurance adjustment may be very complicated. For example, claims that be rejected as duplicates may be adjusted, cancelled or resubmitted. Claims that rejected for eligibility or other billing errors may be adjusted when the eligibility or billing issue is resolved. At different times, billing transactions that have previously processed may be paid or repaid with a duplicate payment. The Division of Medicaid and the fiscal agent allow adjusting and voiding of claims. If a paid claim is being adjusted, the Provider Identification Number and the Recipient cannot be changed. The voided amount originally paid will appear as a negative amount and that amount will be deducted from payments until the overpayment is recovered. Usually we have a void claim identifier which can be used to as an edit in the system to exclude the voided claims. Sometimes since some database or data warehouse is not real time and has different updating time, the voided claims identifier will not be effective or even exist in the system. For the same insurance ID, we have positive or negative amount charged which can be offset eventually. For these claims, we will remove them as voided claims before calculating any overpayments. SAS CODES ****************************************************************************; * Remove Void Insurance Claims ; ****************************************************************************; %macro remove_void(indata, outdata); *clear data before deleting voids; set &indata.; if verify(id, '8') ~= ' ' and amount_charged not in (.,0); *create partial void claim IDs; set temp; length voidid $200; amc1=floor(abs(amount_charged)); amc=put(amc1, 20.); insert='int'; voidid=cats(id, insert, amc); 1
drop amc1 amc insert; *Sort dataset by void ID and amount_charged ascendingly; proc sort data=temp; by voidid amount_charged; set temp; by voidid amount_charged; retain s1 0; if first.amount_charged then s1=0; if amount_charged >0 then s1=s1+1; *Sort dataset by void ID and amount_charged descendingly; proc sort data=temp; by voidid descending amount_charged; set temp; by voidid descending amount_charged; retain s2 0; if first.amount_charged then s2=0; if amount_charged < 0 then s2=s2+1; *Get the void claim flags; proc sql; create table flag_temp as select *, max(s1) as max_s1, max(s2) as max_s2 from temp group by voidid; quit; data flag_temp; set flag_temp; if max_s1=max_s2 then void_flag='y'; else if max_s1 < max_s2 then do; if s2<=max_s1 then void_flag ='Y'; else void_flag='n'; end; else do; if s1<=max_s2 then void_flag ='Y'; else void_flag='n'; end; if max_s1=0 or max_s2 =0 then void_flag='n'; *Remove the void claims; data voids; set flag_temp; if void_flag='y'; data novoids; set flag_temp; 2
if void_flag='n'; data &outdata.; set novoids; drop voidid s1 s2 max_s1 max_s2 void_flag; %mend remove_void; *Read in the insurance data; data insurance; infile "C:\Documents and Settings\shiq\Desktop\New Folder\WUSS\void.txt"; input id $6. amount_charged tpl adjustment_indicator; *use the macro to Remove the void claims; options symbolgen mprint mlogic; %remove_void(insurance, insurance_novoids); RESULTS The demonstrated data set INSURANCE has 22 observations and 4 variables. One variable is called ID which represents the claim identifications. AMOUNT_CHARGED means the provider charged on the insurance agents or companies. TPL represents the other third party payment to this claim. ADJUSTMENT_INDICATOR provides codes for different adjustment activities. Here the code 0 represents the original claims. The other codes mean claims with different partial adjustments. Table 1: The Dataset INSURANCE used as an example. 3
For the same claim ID, there are different records with different adjustments and third party payments. We want to find out the voided claims remove them from the above table. The following is the intermediate table derived from INSURANCE containing the check results for voided claims for the same claim IDs. Table 2: Dataset TEMP used to check voided claims for the same claim IDs. The field VOIDID is a concatenation of the insurance claim ID and the amount charged. Between ID and AMOUNT_CHARGED, there are three characters INT to differentiate these two values in the field of VOIDID. The field S1 is created to count the number of positive charged amounts for the same VOIDID. First we sort the dataset by VOIDID and ascending AMOUNT_CHARGED. Then for the first value of VOIDID in the sorting of AMOUNT_CHARGED, initialize S1=0. For positive amount charged, S1=S1+1. Retain the value of S1 for the same VOIDID. Repeat these steps until we get all the S1 values. The field S2 is created to count the number of negative charged amounts for the same VOIDID. First we sort the dataset by VOIDID and descending AMOUNT_CHARGED. Then for the first value of VOIDID in the sorting of AMOUNT_CHARGED, initialize S2=0. For negative amount charged, S2=S2+1. Retain the value of S2 for the same VOIDID. Repeat these steps until we get all the S2 values. Table 3: Dataset FLAG_TEMP. 4
From table 3, we can get the voided claim flags for all the records. The field VOID_FLAG is created. If VOID_FLAG = Y then this claim record is voided. If VOID_FLAG = N then this claim record is not voided. The MAX_S1 is the total number of positive charged amounts for the insurance claim ID. The MAX_S2 is the total number of negative charged amounts for the insurance claim ID. If MAX_S1 = MAX_S2, then all the records related to this claim ID will be identified as voided. If MAX_S1 < MAX_S2, then for all the records with S2 <= MAX_S1 assign VOID_FLAG = Y, otherwise VOID_FLAG = N. If MAX_S1 > MAX_S2, then for all the records with S1 <= MAX_S2 assign VOID_FLAG = Y, otherwise VOID_FLAG = N. If the insurance ID only have positive or negative charged amounts which means MAX_S1 =0 or MAX_S2 =0, then let VOID_FLAG = N for all the records of this insurance ID. Table 4: Dataset VOIDS. From table 4, we know that there are 12 voided claims altogether with VOID_FLAG = Y. Table 5: Dataset NOVOIDS. 5
From table 5, we know that there are 10 valid claims with VOID_FLAG = N. To get the final output dataset, we can simply drop the fields like VOIDID, S1, S2, MAX_S1, MAX_S2 and VOID_FLAG. REFERENCES 1. Detecting Medicaid Data Anomalies Using Data Mining Techniques, Southeast SAS Users Group Conference, 2010. 2. Find Potential Fraud Leads Using Data Mining Techniques, Southeast SAS Users Group Conference, 2011. 3. Assign Overpayment to Insurance Data with Adjustments, Southeast SAS Users Group Conference, 2011. CONTACT INFORMATION Your comments and questions are valued and encouraged. Contact the author at: Qiling Shi, Mathematics PhD, Certified Fraud Examiner Email: shiqiling@gmail.com SAS and all other SAS Institute Inc. product or service names are registered trademarks or trademarks of SAS Institute Inc. in the USA and other countries. indicates USA registration. Other brand and product names are trademarks of their respective companies. 6