Thanks again Tom, this worked perfectly! Finally got it to work by joining the claims data with the vendor data by MBR_ID, DOS & NPI to give me the records I needed then, I split this joined file into two tables, one with vendor info and one with our claims info. then I could use the match merge to get the output I was looking for. Here is a look at the code- FYI, not all of this will be used in the final process, it was used here to validate my output: %MACRO UTL_LIBS();
%INCLUDE '/source/riskadj/informatics/LIBNAMES/DECLARE_LIBRARIES.sas';
%MEND UTL_LIBS;
%UTL_LIBS();
RUN;
LIBNAME Vineeth '/data152/riskadj2/vin';
LIBNAME model_18 '/data152/riskadj2/vin/2018Model';
libname Merx '/data152/riskadj2/HH/medicarerx';
LIBNAME Medical '/data150/rari/Medical';
LIBNAME Hao '/data156/mgm_cra/mgm_test/';
LIBNAME Member '/data143/mcrf_ap2/prod/membership/input';
LIBNAME R2016_2 '/data152/riskadj2/informatics/retrospective/201611';
LIBNAME R2019_2 '/data152/riskadj2/informatics/retrospective/201912';
LIBNAME R2020 '/data152/riskadj2/informatics/retrospective/202007';
LIBNAME CLM2020 '/data166/riskadj/DW_Register/_202106';
LIBNAME MRA20202 '/data156/mgm_mra/Retro2020_2';
LIBNAME MRA2020 '/data156/mgm_mra/Retro2020';
LIBNAME ATHENA '/data198/crmo_app/prod/athena/load';
LIBNAME AS '/data198/crmo_app/prod/allscripts/load';
LIBNAME ECW '/data198/crmo_app/prod/ecw/load';
LIBNAME MOXE '/data198/crmo_app/prod/moxe/load';
LIBNAME NEXTGEN '/data198/crmo_app/prod/nextgen/load';
LIBNAME KS '/data152/riskadj2/informatics/ks';
LIBNAME R2021 '/data152/riskadj2/informatics/retrospective/202108';
LIBNAME MDCR_III '/data156/mgm/MEDICARE_INPUT';
lIBNAME MRA2021 '/data156/mgm_mra/Retro2021';
LIBNAME SVP '/data152/riskadj2/informatics/SVP';
libname ATRAC '/data152/riskadj2/informatics/ATRAC';
libname R2020_2 '/data152/riskadj2/informatics/retrospective/202012';
libname ATRAC '/data152/riskadj2/informatics/ATRAC';
libname R2020_2 '/data152/riskadj2/informatics/retrospective/202012';
/* 1. Get ATRAC file & rename variables to match claims file */
PROC SQL;
CREATE TABLE CCR2021A as
SELECT distinct
ID,
MemberID,
MemberIndividualID as ENRLE_ID,
ProviderType,
DateOfServiceFrom as STMT_STRT_DT,
DateOfServiceTo as STMT_STOP_DT,
RenNPI as SVCG_PVDR_NPI_NBR,
ICDDisposition,
RenTIN as SVCG_PVDR_TIN_NBR,
RenPIN as SVCG_PVDR_PIN_TXT,
ChaseID,
ClaimID,
ICDCODE as CDF_DX
FROM atrac.TBLIMPORTEDRAPSDATA2020(obs=10000);
QUIT;
/* 2. Get claim data & join with dx data */
/* MUST BE A LEFT JOIN */
/* Left join = everything from Claims_raw & only what matches from Claims_dx*/
/* Inner join = ONLY what matches from both sets */
PROC SQL;
CREATE TABLE CLAIMSA AS
SELECT DISTINCT
a.CLM_ID,
a.SRC_CLM_ID,
a.STMT_STRT_DT,
a.STMT_STOP_DT,
a.ENRLE_ID,
a.SVCG_PVDR_NPI_NBR,
a.SVCG_PVDR_PIN_TXT,
a.SVCG_PVDR_TIN_NBR,
b.CLM_ID,
b.ICD9_DX_CD as CLM_DX
FROM R2020_2.CLAIMS_RAW a
LEFT JOIN R2020_2.RRODS_CLAIM_DX b ON
ICD9_DX_CD=compress(ICD9_DX_CD,".") AND
a.CLM_ID = b.CLM_ID ;
QUIT;
/* THIS TABLE JOINS CLAIMS AND ATRAC REGARDLESS OF DX */
/* SINCE WE ONLY WANT INFORMATION ON CLAIMS THAT WERE SENT TO THE VENDOR */
/* AND MATCH OUR VENDOR FILE VIA MBR ID, DOS & NPI, */
/* IF YOU DO AN INNER JOIN, WE ONLY GET WHAT MATCHED IN BOTH */
/* A LEFT JOIN WILL GIVE ME EVERYTHING FROM THE VENDOR FILE AND ONLY */
/* WHAT MATCHES IN CLAIMS-THIS WILL GIVE ME EXTRA ATRAC RECORDS THAT I DON'T NEED */
/* THIS JOIN YIELDED 10,853 RECORDS WHICH IS 853 MORE THAN EXPECTED */
/* ADDITIONALLY, IT ISN'T LIKELY THAT EVERY ATRAC FILE WAS MATCHED TO A CLAIM */
PROC SQL;
CREATE TABLE SVP_A AS
SELECT DISTINCT
a.ID,
a.MemberID,
a.ENRLE_ID,
a.ICDDisposition,
a.ChaseID,
a.ClaimID,
a.CDF_DX,
a.SVCG_PVDR_NPI_NBR,
a.SVCG_PVDR_PIN_TXT,
a.SVCG_PVDR_TIN_NBR,
a.STMT_STRT_DT,
a.STMT_STOP_DT,
b.ENRLE_ID,
b.CLM_ID,
b.SRC_CLM_ID,
b.SVCG_PVDR_NPI_NBR,
b.SVCG_PVDR_PIN_TXT,
b.SVCG_PVDR_TIN_NBR,
b.STMT_STRT_DT,
b.STMT_STOP_DT,
b.CLM_DX
FROM CCR2021A a
FULL JOIN CLAIMSA b ON
a.ENRLE_ID=B.ENRLE_ID AND
a.STMT_STRT_DT=b.STMT_STRT_DT AND
a.STMT_STOP_DT=b.STMT_STOP_DT AND
a.SVCG_PVDR_NPI_NBR=b.SVCG_PVDR_NPI_NBR;
QUIT;
/* THIS TABLE JOINS CLAIMS AND ATRAC REGARDLESS OF DX */
/* SINCE WE ONLY WANT INFORMATION ON CLAIMS THAT WERE SENT TO THE VENDOR */
/* AND MATCH OUR VENDOR FILE VIA MBR ID, DOS & NPI, */
/* IF YOU DO AN INNER JOIN, WE ONLY GET WHAT MATCHED IN BOTH */
/* A LEFT JOIN WILL GIVE ME EVERYTHING FROM THE VENDOR FILE AND ONLY */
/* WHAT MATCHES IN CLAIMS-THIS WILL GIVE ME EXTRA ATRAC RECORDS THAT I DON'T NEED */
/* THIS JOIN YIELDED 10,853 RECORDS WHICH IS 853 MORE THAN EXPECTED */
/* ADDITIONALLY, IT ISN'T LIKELY THAT EVERY ATRAC FILE WAS MATCHED TO A CLAIM */
/* ADDING ANOTHER QUALIFIER HERE, DX CODE */
/* INNER JOIN RESULTS NOT AS EXPECTED, TRY LEFT JOIN THEN FULL */
PROC SQL;
CREATE TABLE SVP_A AS
SELECT DISTINCT
a.ID,
a.MemberID,
a.ENRLE_ID,
a.ICDDisposition,
a.ChaseID,
a.ClaimID,
a.CDF_DX,
a.SVCG_PVDR_NPI_NBR,
a.SVCG_PVDR_PIN_TXT,
a.SVCG_PVDR_TIN_NBR,
a.STMT_STRT_DT,
a.STMT_STOP_DT,
b.ENRLE_ID,
b.CLM_ID,
b.SRC_CLM_ID,
b.SVCG_PVDR_NPI_NBR,
b.SVCG_PVDR_PIN_TXT,
b.SVCG_PVDR_TIN_NBR,
b.STMT_STRT_DT,
b.STMT_STOP_DT,
b.CLM_DX
FROM CCR2021A a
INNER JOIN CLAIMSA b ON
a.ENRLE_ID=B.ENRLE_ID AND
a.STMT_STRT_DT=b.STMT_STRT_DT AND
a.STMT_STOP_DT=b.STMT_STOP_DT AND
a.SVCG_PVDR_NPI_NBR=b.SVCG_PVDR_NPI_NBR AND
a.CDF_DX=b.CLM_DX;
QUIT;
/* THIS TABLE JOINS CLAIMS AND ATRAC REGARDLESS OF DX */
/* SINCE WE ONLY WANT INFORMATION ON CLAIMS THAT WERE SENT TO THE VENDOR */
/* AND MATCH OUR VENDOR FILE VIA MBR ID, DOS & NPI, */
/* IF YOU DO AN INNER JOIN, WE ONLY GET WHAT MATCHED IN BOTH */
/* A LEFT JOIN WILL GIVE ME EVERYTHING FROM THE VENDOR FILE AND ONLY */
/* WHAT MATCHES IN CLAIMS-THIS WILL GIVE ME EXTRA ATRAC RECORDS THAT I DON'T NEED */
/* THIS JOIN YIELDED 10,853 RECORDS WHICH IS 853 MORE THAN EXPECTED */
/* ADDITIONALLY, IT ISN'T LIKELY THAT EVERY ATRAC FILE WAS MATCHED TO A CLAIM */
/* ADDING ANOTHER QUALIFIER HERE, DX CODE */
/* INNER JOIN RESULTS NOT AS EXPECTED, TRY LEFT JOIN THEN FULL */
/* THIS CODE GIVES US THE BEST OUTPUT IN JOINING CLAIMS TO CDF */
/* a.CDF_DX= ' ' AND b.CLM_DX NE ' '; = DELETE */
/* AND, SHOWS WHICH RECORDS HAVE CLAIM ICD AND NOT CDF ICD WHICH = DELETES */
/* HOWEVER, THIS IS ONLY WHERE CDF ICDS ARE BLANK */
/* ADDITIONALLY, IN CURRENT STATE, THE VENDOR DIDN'T POPULATE THE DX CODE */
/* THEY JUST NOTED IN ICD DISPOSITION THAT IT IS VALID SO THIS IS A FALSE POSITIVE */
/* FUTURE STATE, THERE SHOULDN'T BE ANY BLANK ICDCODES FROM THE VENDOR OR, VERY FEW */
/* SO, IF I REVERSE THE CODE ABOVE, CDF IS NOT BLANK WHILE CLM DX IS BLANK = ADDS */
/* a.CDF_DX NE ' ' AND b.CLM_DX= ' '; = ADDS */
PROC SQL;
CREATE TABLE SVP_A AS
SELECT DISTINCT
a.ID,
a.MemberID,
a.ENRLE_ID,
a.ICDDisposition,
a.ChaseID,
a.ClaimID,
a.CDF_DX,
a.SVCG_PVDR_NPI_NBR,
a.SVCG_PVDR_PIN_TXT,
a.SVCG_PVDR_TIN_NBR,
a.STMT_STRT_DT,
a.STMT_STOP_DT,
b.ENRLE_ID,
b.CLM_ID,
b.SRC_CLM_ID,
b.SVCG_PVDR_NPI_NBR,
b.SVCG_PVDR_PIN_TXT,
b.SVCG_PVDR_TIN_NBR,
b.STMT_STRT_DT,
b.STMT_STOP_DT,
b.CLM_DX
FROM CCR2021A a
INNER JOIN CLAIMSA b ON
a.ENRLE_ID=B.ENRLE_ID AND
a.STMT_STRT_DT=b.STMT_STRT_DT AND
a.STMT_STOP_DT=b.STMT_STOP_DT AND
a.SVCG_PVDR_NPI_NBR=b.SVCG_PVDR_NPI_NBR AND
a.CDF_DX NE ' ' AND
b.CLM_DX= ' ';
QUIT;
/* THIS TABLE JOINS CLAIMS AND ATRAC REGARDLESS OF DX */
/* SINCE WE ONLY WANT INFORMATION ON CLAIMS THAT WERE SENT TO THE VENDOR */
/* AND MATCH OUR VENDOR FILE VIA MBR ID, DOS & NPI, */
/* IF YOU DO AN INNER JOIN, WE ONLY GET WHAT MATCHED IN BOTH */
/* A LEFT JOIN WILL GIVE ME EVERYTHING FROM THE VENDOR FILE AND ONLY */
/* WHAT MATCHES IN CLAIMS-THIS WILL GIVE ME EXTRA ATRAC RECORDS THAT I DON'T NEED */
/* THIS JOIN YIELDED 10,853 RECORDS WHICH IS 853 MORE THAN EXPECTED */
/* ADDITIONALLY, IT ISN'T LIKELY THAT EVERY ATRAC FILE WAS MATCHED TO A CLAIM */
/* ADDING ANOTHER QUALIFIER HERE, DX CODE */
/* INNER JOIN RESULTS NOT AS EXPECTED, TRY LEFT JOIN THEN FULL */
/* THIS CODE GIVES US THE BEST OUTPUT IN JOINING CLAIMS TO CDF */
/* a.CDF_DX= ' ' AND b.CLM_DX NE ' '; = DELETE */
/* AND, SHOWS WHICH RECORDS HAVE CLAIM ICD AND NOT CDF ICD WHICH = DELETES */
/* HOWEVER, THIS IS ONLY WHERE CDF ICDS ARE BLANK */
/* ADDITIONALLY, IN CURRENT STATE, THE VENDOR DIDN'T POPULATE THE DX CODE */
/* THEY JUST NOTED IN ICD DISPOSITION THAT IT IS VALID SO THIS IS A FALSE POSITIVE */
/* FUTURE STATE, THERE SHOULDN'T BE ANY BLANK ICDCODES FROM THE VENDOR OR, VERY FEW */
/* SO, IF I REVERSE THE CODE ABOVE, CDF IS NOT BLANK WHILE CLM DX IS BLANK = ADDS */
/* a.CDF_DX NE ' ' AND b.CLM_DX= ' '; = ADDS */
/* WILL SETTING CDF_DX NE TO CLM_DX GIVE ME DELETES? */
PROC SQL;
CREATE TABLE SVP_A AS
SELECT DISTINCT
a.ID,
a.MemberID,
a.ENRLE_ID,
a.ICDDisposition,
a.ChaseID,
a.ClaimID,
a.CDF_DX,
a.SVCG_PVDR_NPI_NBR,
a.SVCG_PVDR_PIN_TXT,
a.SVCG_PVDR_TIN_NBR,
a.STMT_STRT_DT,
a.STMT_STOP_DT,
b.ENRLE_ID,
b.CLM_ID,
b.SRC_CLM_ID,
b.SVCG_PVDR_NPI_NBR,
b.SVCG_PVDR_PIN_TXT,
b.SVCG_PVDR_TIN_NBR,
b.STMT_STRT_DT,
b.STMT_STOP_DT,
b.CLM_DX
FROM CCR2021A a
INNER JOIN CLAIMSA b ON
a.ENRLE_ID=B.ENRLE_ID AND
a.STMT_STRT_DT=b.STMT_STRT_DT AND
a.STMT_STOP_DT=b.STMT_STOP_DT AND
a.SVCG_PVDR_NPI_NBR=b.SVCG_PVDR_NPI_NBR AND
a.CDF_DX NE ' ' AND
b.CLM_DX NE ' ' AND
a.CDF_DX NE b.CLM_DX;
QUIT;
/* THIS TABLE JOINS CLAIMS AND ATRAC REGARDLESS OF DX */
/* SINCE WE ONLY WANT INFORMATION ON CLAIMS THAT WERE SENT TO THE VENDOR */
/* AND MATCH OUR VENDOR FILE VIA MBR ID, DOS & NPI, */
/* IF YOU DO AN INNER JOIN, WE ONLY GET WHAT MATCHED IN BOTH */
/* A LEFT JOIN WILL GIVE ME EVERYTHING FROM THE VENDOR FILE AND ONLY */
/* WHAT MATCHES IN CLAIMS-THIS WILL GIVE ME EXTRA ATRAC RECORDS THAT I DON'T NEED */
/* THIS JOIN YIELDED 10,853 RECORDS WHICH IS 853 MORE THAN EXPECTED */
/* ADDITIONALLY, IT ISN'T LIKELY THAT EVERY ATRAC FILE WAS MATCHED TO A CLAIM */
/* ADDING ANOTHER QUALIFIER HERE, DX CODE */
/* INNER JOIN RESULTS NOT AS EXPECTED, TRY LEFT JOIN THEN FULL */
/* THIS CODE GIVES US THE BEST OUTPUT IN JOINING CLAIMS TO CDF */
/* a.CDF_DX= ' ' AND b.CLM_DX NE ' '; = DELETE */
/* AND, SHOWS WHICH RECORDS HAVE CLAIM ICD AND NOT CDF ICD WHICH = DELETES */
/* HOWEVER, THIS IS ONLY WHERE CDF ICDS ARE BLANK */
/* ADDITIONALLY, IN CURRENT STATE, THE VENDOR DIDN'T POPULATE THE DX CODE */
/* THEY JUST NOTED IN ICD DISPOSITION THAT IT IS VALID SO THIS IS A FALSE POSITIVE */
/* FUTURE STATE, THERE SHOULDN'T BE ANY BLANK ICDCODES FROM THE VENDOR OR, VERY FEW */
/* SO, IF I REVERSE THE CODE ABOVE, CDF IS NOT BLANK WHILE CLM DX IS BLANK = ADDS */
/* a.CDF_DX NE ' ' AND b.CLM_DX= ' '; = ADDS */
/* 10:44 am 08.13.21 - SAVING SVP_A WITHOUT THE DX QUALIFIER */
/* TO TEST THE DX MATCHING INDEPENDENTLY */
PROC SQL;
CREATE TABLE SVP_A AS
SELECT DISTINCT
a.ID,
a.MemberID,
a.ENRLE_ID,
a.ICDDisposition,
a.ChaseID,
a.ClaimID,
a.CDF_DX,
a.SVCG_PVDR_NPI_NBR,
a.SVCG_PVDR_PIN_TXT,
a.SVCG_PVDR_TIN_NBR,
a.STMT_STRT_DT,
a.STMT_STOP_DT,
b.ENRLE_ID,
b.CLM_ID,
b.SRC_CLM_ID,
b.SVCG_PVDR_NPI_NBR,
b.SVCG_PVDR_PIN_TXT,
b.SVCG_PVDR_TIN_NBR,
b.STMT_STRT_DT,
b.STMT_STOP_DT,
b.CLM_DX
FROM CCR2021A a
INNER JOIN CLAIMSA b ON
a.ENRLE_ID=B.ENRLE_ID AND
a.STMT_STRT_DT=b.STMT_STRT_DT AND
a.STMT_STOP_DT=b.STMT_STOP_DT AND
a.SVCG_PVDR_NPI_NBR=b.SVCG_PVDR_NPI_NBR;
QUIT;
DATA SVP_B; SET SVP_A;
RUN;
/*USING THE DATA IN SVP_A, REMOVED ALL RECORDS WHERE BOTH THE CDF DX AND CLM DX ARE BLANK */
/*CURRENT STATE, THESE COULD BE VALID OR ASRs BUT, FUTURE STATE IF THE CDF DX IS BLANK, */
/*THAT WOULD INDICATE THE VENDOR COULDN'T 'FIND/DETERMINE' A DX CODE */
/*WE MAY WANT TO LOOK AT THESE RECORDS TO IMPROVE OUR CHASE SELECTION */
/* 2,915 RECORDS MET THIS CRITERIA */
PROC SQL;
CREATE TABLE SVP_C AS
SELECT DISTINCT *
FROM SVP_B
WHERE CDF_DX = ' ' AND
CLM_DX = ' ';
QUIT;
/*USING SVP_B, REMOVE THE RECORDS IDENTIFIED IN SVP_C */
PROC SQL;
CREATE TABLE SVP_D AS
SELECT DISTINCT *
FROM SVP_B
WHERE CDF_DX NE ' ' AND
CLM_DX NE ' ';
QUIT;
/* USING SVP_D WHERE THE CLAIM MATCH IS COMPLETE, CREATE TWO DATASETS */
/* ONE WITH CLAIM INFO AND THE OTHER WITH CDF INFO */
/* FOR THE PURPOSES OF MATCH MERGING THE ICD CODES */
/* MM1 = CDF DATA AND MM2 = CLM DATA */
PROC SQL;
CREATE TABLE SVP_MM_1 AS
SELECT DISTINCT
ID,
MemberID,
ENRLE_ID,
ICDDisposition,
ChaseID,
ClaimID,
CDF_DX AS CLM_DX,
SVCG_PVDR_NPI_NBR,
SVCG_PVDR_PIN_TXT,
SVCG_PVDR_TIN_NBR,
STMT_STRT_DT,
STMT_STOP_DT
FROM SVP_D;
QUIT;
/* USING SVP_B WHERE THE CLAIM MATCH IS COMPLETE, CREATE TWO DATASETS */
/* ONE WITH CLAIM INFO AND THE OTHER WITH CDF INFO */
/* FOR THE PURPOSES OF MATCH MERGING THE ICD CODES */
/* MM1 = CDF DATA AND MM2 = CLM DATA */
PROC SQL;
CREATE TABLE SVP_MM_2 AS
SELECT DISTINCT
ID,
MemberID,
ENRLE_ID,
ICDDisposition,
ChaseID,
ClaimID,
CLM_DX,
CLM_ID,
SRC_CLM_ID,
SVCG_PVDR_NPI_NBR,
SVCG_PVDR_PIN_TXT,
SVCG_PVDR_TIN_NBR,
STMT_STRT_DT,
STMT_STOP_DT
FROM SVP_D;
QUIT;
/* NOW, USING MM1 AND MM2, ATTEMPT TO MERGE AND GET DX MATCH RESULTS */
/* NEED TO SORT EACH TABLE BY CLM_DX*/
/* NEED TO SORT DATASETS BY KEY VARIABLES IN BY STATEMENT*/
PROC SORT DATA=WORK.SVP_MM_1 OUT=SVP_MM_1B;
BY CLM_DX;
RUN;
PROC SORT DATA=WORK.SVP_MM_2 OUT=SVP_MM_2B;
BY CLM_DX;
data VAL_1;
merge SVP_MM_1B(in=in1) SVP_MM_2B(in=in2);
by CLM_DX CLM_DX ;
length match_type $8 ;
if in1 and in2 then match_type='BOTH';
else if in2 then match_type='ADD';
else match_type='DELETE';
run;
... View more