-
Notifications
You must be signed in to change notification settings - Fork 7
/
check_ds_ae_discon.R
137 lines (112 loc) · 4.08 KB
/
check_ds_ae_discon.R
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#' @title Check for treatment discontinuation consistency between DS and AE
#'
#' @description This check looks for consistency when DS.DSSPID=DISCTX*
#' then there should be AE.AEACN[n]=DRUG WITHDRAWN
#'
#' @param AE Adverse Events SDTM dataset with variables USUBJID, AEDECOD,
#' AESTDTC, AEACN[n]
#'
#' @param DS Disposition SDTM dataset with variables USUBJID, DSSPID, DSCAT,
#' DSDECOD, DSSTDTC
#'
#' @return boolean value if check failed or passed with 'msg' attribute if the
#' test failed
#'
#' @importFrom dplyr distinct
#'
#' @export
#'
#' @author Sarwan Singh
#'
#' @examples
#'
#' AE <- data.frame(
#' USUBJID = 1:5,
#' AESTDTC = "01JAN2017",
#' AETERM = c("AE1","AE2","AE3","AE4","AE5"),
#' AEDECOD = c("AE1","AE2","AE3","AE4","AE5"),
#' AEACN = c("DOSE REDUCED", "DOSE REDUCED", "DOSE NOT CHANGED",
#' "DOSE NOT CHANGED", "NOT APPLICABLE"),
#' stringsAsFactors = FALSE
#' )
#'
#'
#' DS <- data.frame(
#' USUBJID = 1:5,
#' DSSPID = c('XXXDISCTXXXXX'),
#' DSSTDTC = '01JAN2017',
#' DSCAT = rep("DISPOSITION EVENT", 5),
#' DSSCAT = rep("TX FORM", 5),
#' DSDECOD = c("PHYSICIAN DECISION", "OTHER", "PHYSICIAN DECISION", "OTHER", "DEATH"),
#' stringsAsFactors = FALSE
#' )
#'
#' # no case
#' check_ds_ae_discon(DS, AE)
#'
#' # 1 case
#' DS[3, "DSDECOD"] <- 'ADVERSE EVENT'
#' check_ds_ae_discon(DS, AE)
#'
#' # mutliple AEACNx
#' AE <- data.frame(
#' USUBJID = 1:5,
#' AESTDTC = c("01JAN2017"),
#' AETERM = c("AE1","AE2","AE3","AE4","AE5"),
#' AEDECOD = c("AE1","AE2","AE3","AE4","AE5"),
#' AEACN = rep("MULTIPLE", 5),
#' AEACN1 = c("DOSE REDUCED", "DOSE NOT CHANGED", "DOSE NOT CHANGED",
#' "DOSE NOT CHANGED", "NOT APPLICABLE"),
#' stringsAsFactors = FALSE
#' )
#'
#' check_ds_ae_discon(DS, AE)
#'
## Check for missing death dates when ae outcomes are fatal.
check_ds_ae_discon <- function(DS, AE){
###First check that required variables exist and return a message if they don't
if(AE %lacks_any% c("USUBJID", "AETERM", "AEDECOD", "AESTDTC","AEACN")){
fail(lacks_msg(AE, c("USUBJID", "AETERM", "AEDECOD", "AESTDTC","AEACN")))
} else if(DS %lacks_any% c("USUBJID", "DSSPID", "DSCAT","DSSCAT", "DSDECOD", "DSSTDTC")){
fail(lacks_msg(DS, c("USUBJID", "DSSPID", "DSCAT","DSSCAT", "DSDECOD", "DSSTDTC")))
} else{
# keep variables on which we want to check action taken with treatment
ae0 <- subset(AE,
select = c("USUBJID", "AETERM", "AEDECOD", "AESTDTC", "AEACN",
grep("AEACN[0-9]", names(AE), value=TRUE)))
# select if AE dataset has AEACNx variables
aeacnvars <- grep("AEACN[0-9]", names(ae0), value=TRUE)
#create a where condition for AE
whrcond <- paste("AEACN=='DRUG WITHDRAWN'")
for (i in aeacnvars) {
whrcond <- paste(whrcond, " | ", i, "=='DRUG WITHDRAWN'", sep="")
}
# loop through each AEACNx and keep DRUG WITHDRAWN AEs
ae1 <- subset(ae0,
eval(parse(text = whrcond)) )
# keep unique usubjid
ae2 <- distinct(ae1, USUBJID, .keep_all = TRUE)
# keep records with discontinuation treatment due to AE
ds0 <- subset(DS,
DSCAT == 'DISPOSITION EVENT' & grepl("DISCTX", DSSPID) &
DSDECOD == 'ADVERSE EVENT',
select = c("USUBJID", "DSSPID", "DSSCAT", "DSDECOD", "DSSTDTC" ))
finout <- merge(ae2, ds0,
by= "USUBJID",
all = TRUE)
# check if DS record with AE has corresponding record in AE
mydf <- subset(finout,
is_sas_na(AETERM),
select = c("USUBJID", "DSSCAT", "DSDECOD", "DSSTDTC")
)
rownames(mydf)=NULL
### Return message if no inconsistency between AEOUT and AEDTHDTC
if(nrow(mydf)==0){
pass()
### Return subset dataframe if there are records with inconsistency
}else if(nrow(mydf)>0){
return(fail(paste(length(unique(mydf$USUBJID)),
" patient(s) with Treatment Discon due to AE but no AE record indicating drug withdrawn. ",sep=""), mydf))
} #end else if mydf has records
} #end else if required variable exist
} #end check_ds_ae_discon()