-
Notifications
You must be signed in to change notification settings - Fork 0
/
NHS England CKD algorithm
103 lines (87 loc) · 6.51 KB
/
NHS England CKD algorithm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#CKD IS STAGED HERE BASED ON MAINTENANCE OF EACH EGFR LEVEL FOR A MINIMUM OF 3 MONTHS
#CKD HAS BEEN DERIVED HERE FROM CKD-EPI EGFR
load("crea.repv12.rda") #table featuring 1 row per patient per day with maximum creatinine retained
load ("sir.data.rda") #long format input file with 1 row per event entry
#Reduce dataset to individuals eligible for CKD and AKI staging before looping;
#Identify potential creatinine based CKD patients (individuals with any egfr<60)
#Isolate the first qualifying test for each patient
crea.rep$KDmark<-ifelse(!is.na(crea.rep$CKDEPIeGFR) & crea.rep$CKDEPIeGFR<60,1,0)
CKs<-crea.rep[crea.rep$KDmark==1,c("PatientID","EntryDate","KDmark")] #Kidney Injury flagged tests
#Create a dataset including all data from patients with at least 1 KD flag:
CKpot<-crea.rep[crea.rep$PatientID %in% CKs$PatientID,]
CKpot$EntryDate2<-as.Date(as.character(CKpot$EntryDate),format="%Y%m%d")
#Mark a 90 day lookback period
CKpot$EntryDate1<-as.Date(as.character(CKpot$EntryDate),format="%Y%m%d")-90
CKpot<-CKpot[,c("PatientID","event.date","KDmark","EntryDate1","EntryDate2","CKDEPIeGFR")]
############################################################################################## CHECKED
#Diagnose CKD
#If eGFR under 60 is not sustained for 90 days, recode KDmark as 0
for (i in 1:length(CKpot$PatientID)){
CKpot$CKD[i]<-min(crea.rep$KDmark[crea.rep$PatientID==CKpot$PatientID[i] &
crea.rep$event.date>CKpot$EntryDate1[i] & crea.rep$event.date<=CKpot$EntryDate2[i]])
CKpot$MaxCKD[i]<-max(crea.rep$CKDEPIeGFR[crea.rep$PatientID==CKpot$PatientID[i] &
crea.rep$event.date>CKpot$EntryDate1[i] & crea.rep$event.date<=CKpot$EntryDate2[i]])
CKpot$MinCKD[i]<-min(crea.rep$CKDEPIeGFR[crea.rep$PatientID==CKpot$PatientID[i] &
crea.rep$event.date>CKpot$EntryDate1[i] & crea.rep$event.date<=CKpot$EntryDate2[i]])
}
#CKD is 1 if the test qualifies and there is no normal test within 3 months prior
#At this stage some are temporarily falsely positively identified that have no lookback test
#Near date match EntryDate1 (90 days prior date)- to entries from the full dataset
#neardate preferably matches to a prior entry if one is available
#if the closest match is before EntryDate1 (data from more than 90 days prior available), retain row.
indx1<-neardate(CKpot$PatientID,crea.rep$PatientID,CKpot$EntryDate1,crea.rep$event.date,best="prior",nomatch=NA_integer_)
CKpot$Lookback<-crea.rep[indx1,"event.date"]
CKpot$CKDGStage<-ifelse(CKpot$Lookback<=CKpot$EntryDate1 & CKpot$CKDE==1,1,0)
CKpot<-CKpot[CKpot$CKDGStage==1,]
#CKpot is a subset table of CKD qualifying tests and their markers to be merged onto crea.rep
CKpot<-unique(CKpot)
crea.rep<-merge(crea.rep,CKpot[,c(1,2,8:10)],all.x=TRUE)
crea.rep$CKDGStage<-ifelse(!is.na(crea.rep$CKDGStage),2,0)
#Stage 1 is skipped here as it cannot be identified from creatinine only, start by coding all as stage 2
table(crea.rep$CKDGStage)
crea.rep$CKDGStage<-ifelse(crea.rep$CKDGStage>0&crea.rep$MaxCKD>=30&crea.rep$MaxCKD<45,3.5,crea.rep$CKDGStage)
crea.rep$CKDGStage<-ifelse(crea.rep$CKDGStage>0&crea.rep$MaxCKD>=45&crea.rep$MaxCKD<60,3,crea.rep$CKDGStage)
crea.rep$CKDGStage<-ifelse(crea.rep$CKDGStage>0&crea.rep$MaxCKD>=15&crea.rep$MaxCKD<30,4,crea.rep$CKDGStage)
crea.rep$CKDGStage<-ifelse(crea.rep$CKDGStage>0&crea.rep$MaxCKD<15,5,crea.rep$CKDGStage)
crea.rep$CKDGStage<-ifelse(is.na(crea.rep$CKDGStage),0,crea.rep$CKDGStage)
table(crea.rep$CKDGStage)
#can replace with dplyr
#Recode to KDIGO
crea.rep$CKDGStage<-ifelse(crea.rep$CKDGStage==3.5,paste("3b"),paste(crea.rep$CKDGStage))
crea.rep$MaxCKDGStage<-ifelse(crea.rep$MaxCKDGStage==3.5,paste("3b"),paste(crea.rep$MaxCKDGStage))
#########################################################################################################
#Mark start of first CKD diagnosis based on creatinine only
CKs<-CKpot %>%
group_by(PatientID)%>%
slice(which.min(EntryDate1)) %>%
as.data.frame
CKs<-CKs[,c(1,2)]
names(CKs)<-c("PatientID","CKDG_Date")
crea.rep<-merge(crea.rep,CKs,all.x=TRUE)
crea.rep$TimeSinceCKD<-difftime(as.Date(as.character(crea.rep$EntryDate),format="%Y%m%d"),crea.rep$CKDG_Date,unit="days")
########################################################################################################
#Incorporate Urine Albumin to creatinine ratio data if available:
crea.rep$CKDAStage<-ifelse(crea.rep$UACratio<3,1,0)
crea.rep$CKDAStage<-ifelse(crea.rep$UACratio>=3&crea.rep$UACratio<30&!crea.rep$CKDGStage=="0",2,crea.rep$CKDAStage)
crea.rep$CKDAStage<-ifelse(crea.rep$UACratio>30&!crea.rep$CKDGStage=="0",3,crea.rep$CKDAStage)
#Stage CKD based on both UAC and creatinine data:
crea.rep$CKDPrognosis<-crea.rep$CKDGStage
crea.rep$CKDPrognosis<-ifelse(crea.rep$CKDGStage<=2 & crea.rep$CKDAStage==2,1,crea.rep$CKDPrognosis)
crea.rep$CKDPrognosis<-ifelse(crea.rep$CKDGStage<=2 & crea.rep$CKDAStage==3,2,crea.rep$CKDPrognosis)
crea.rep$CKDPrognosis<-ifelse(crea.rep$CKDGStage>=3,3,crea.rep$CKDPrognosis)
crea.rep$CKDPrognosis<-ifelse(crea.rep$CKDGStage==3.5 & crea.rep$CKDAStage==1,2,crea.rep$CKDPrognosis)
crea.rep$CKDPrognosis<-ifelse(crea.rep$CKDGStage==3 & crea.rep$CKDAStage==1,1,crea.rep$CKDPrognosis)
crea.rep$CKDPrognosis<-ifelse(crea.rep$CKDGStage==3 & crea.rep$CKDAStage==2,2,crea.rep$CKDPrognosis)
#Where CKD diagnosed based on creatinine, add metric for summarised eGFR range for further phenotyping
crea.rep$CustomeGFR<-ifelse(crea.rep$CKDPrognosis>0 &crea.rep$MaxCKDE>=60 & crea.rep$MaxCKDE<90,1,NA)
crea.rep$CustomeGFR<-ifelse(crea.rep$CKDPrognosis>0 & crea.rep$MaxCKDE>=60 & crea.rep$MaxCKDE<90,1,NA)
crea.rep$CustomeGFR<-ifelse(crea.rep$CKDPrognosis>0 &crea.rep$MaxCKDE>=45 & crea.rep$MaxCKDE<60,2,crea.rep$CustomeGFR)
crea.rep$CustomeGFR<-ifelse(crea.rep$CKDPrognosis>0 &crea.rep$MaxCKDE>=30 & crea.rep$MaxCKDE<45,3,crea.rep$CustomeGFR)
crea.rep$CustomeGFR<-ifelse(crea.rep$CKDPrognosis>0 &crea.rep$MaxCKDE>=15 & crea.rep$MaxCKDE<30,4,crea.rep$CustomeGFR)
crea.rep$CustomeGFR<-ifelse(crea.rep$CKDPrognosis>0 &crea.rep$MaxCKDE<15,5,crea.rep$CustomeGFR)
crea.rep$CustomeGFR2<-ifelse(crea.rep$CKDPrognosis>0 &crea.rep$MinCKDE>=60 & crea.rep$MinCKDE<90,1,NA)
crea.rep$CustomeGFR2<-ifelse(crea.rep$CKDPrognosis>0 & crea.rep$MinCKDE>=60 & crea.rep$MDRDeGFR<90,1,NA)
crea.rep$CustomeGFR2<-ifelse(crea.rep$CKDPrognosis>0 &crea.rep$MinCKDE>=45 & crea.rep$MDRDeGFR<60,2,crea.rep$CustomeGFR)
crea.rep$CustomeGFR2<-ifelse(crea.rep$CKDPrognosis>0 &crea.rep$MinCKDE>=30 & crea.rep$MDRDeGFR<45,3,crea.rep$CustomeGFR)
crea.rep$CustomeGFR2<-ifelse(crea.rep$CKDPrognosis>0 &crea.rep$MinCKDE>=15 & crea.rep$MDRDeGFR<30,4,crea.rep$CustomeGFR)
crea.rep$CustomeGFR2<-ifelse(crea.rep$CKDPrognosis>0 &crea.rep$MinCKDE<15,5,crea.rep$CustomeGFR)