-
Notifications
You must be signed in to change notification settings - Fork 7
/
check_dm_ae_ds_death.R
executable file
·122 lines (105 loc) · 3.64 KB
/
check_dm_ae_ds_death.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
#' @title Check if death reported in DM then death indicator also present in DS or AE
#'
#' @description This checks that when death is indicated in DM with either of DTHFL or
#' DTHDTC then there should be death indicated in either AE or DS.
#'
#' @param AE Adverse Events SDTM dataset with variables USUBJID, AEDTHDTC, AESDTH, AEOUT
#' @param DS Disposition SDTM dataset with variables USUBJID, DSDECOD, DSSTDTC
#' @param DM Demographics SDTM dataset with variables USUBJID, DTHFL, DTHDTC
#'
#' @return boolean value if check failed or passed with 'msg' attribute if the
#' test failed
#'
#' @export
#'
#' @author Sara Bodach
#'
#' @examples
#'
#' AE <- data.frame(
#' STUDYID = 1,
#' USUBJID = 1:3,
#' AEDTHDTC = c(NA,1,NA),
#' AESDTH = c(NA,"Y",NA),
#' AEOUT = c(NA,"FATAL",NA),
#' AETOXGR = c(NA,"5",NA)
#' )
#'
#' DS <- data.frame(
#' STUDYID = 1,
#' USUBJID = 1:3,
#' DSDECOD = c(NA,"DEATH",NA),
#' DSSTDTC = c(NA,"DSDATE",NA)
#' )
#'
#' DM <- data.frame(
#' STUDYID = 1,
#' USUBJID = 1:3,
#' DTHFL=c(NA,"Y","Y"),
#' DTHDTC = c(NA,"DMDATE","DMDATE")
#' )
#'
#' check_dm_ae_ds_death(DM,DS,AE)
#'
#' DS$DSDECOD = NULL
#'
#' check_dm_ae_ds_death(DM,DS,AE)
#'
check_dm_ae_ds_death <- function(DM,DS,AE){
###First check that required variables exist and return a message if they don't
if(AE %lacks_any% c("USUBJID","AEDTHDTC","AEOUT","AESDTH")){
fail(lacks_msg(AE, c("USUBJID","AEDTHDTC","AEOUT","AESDTH")))
}else if(DS %lacks_any% c("USUBJID" ,"DSDECOD","DSSTDTC")){
fail(lacks_msg(DS, c("USUBJID", "DSDECOD","DSSTDTC")))
}else if(DM %lacks_any% c("USUBJID", "DTHFL", "DTHDTC")){
fail(lacks_msg(DM, c("USUBJID", "DTHFL", "DTHDTC")))
} else{
# Get death information from AE, DS, DM
if (AE %has_any% "AETOXGR"){
aedth <- subset(AE,!(is_sas_na(AE$AEDTHDTC)) | AE$AESDTH=="Y" | AE$AEOUT=="FATAL" | AE$AETOXGR=="5",
select=c("USUBJID", "AEDTHDTC", "AETOXGR", "AESDTH", "AEOUT"))
}else{
aedth <- subset(AE,!(is_sas_na(AE$AEDTHDTC)) | AE$AESDTH=="Y" | AE$AEOUT=="FATAL",
select=c("USUBJID", "AEDTHDTC", "AESDTH", "AEOUT"))
}
dsdth <- subset(DS,(DS$DSDECOD=="DEATH"),
select=c("USUBJID", "DSSTDTC"))
dmdth <- subset(DM,!(is_sas_na(DM$DTHDTC)) | DM$DTHFL=="Y",
select=c("USUBJID", "DTHDTC", "DTHFL"))
# Get earliest AE death record
if(nrow(aedth) > 0
){
aedths <- aedth[order(aedth$USUBJID, aedth$AEDTHDTC), ]
aedthsl = unique(aedths)
}else if(nrow(aedth) == 0
){
aedthsl <- aedth
}
# Get earliest DS death record
if(nrow(dsdth) > 0
){
dsdths <- dsdth[order(dsdth$USUBJID, dsdth$DSSTDTC), ]
dsdthsl = unique(dsdths)
}else if(nrow(dsdth)==0
){
dsdthsl <- dsdth
}
# JOIN AE and DS deaths
aeds <- merge(x=aedthsl, y=dsdthsl, by="USUBJID", all=TRUE)
# Get only DM deaths not reported in AE or DS
mydf <- subset(dmdth, !(dmdth$USUBJID %in% aeds$USUBJID))
rownames(mydf)=NULL
###Print to report
### Return message
if(nrow(mydf)==0){
pass()
### Return subset dataframe with death information reported in DM (and not either DS or AE)
}else if(nrow(mydf)>0){
fail(
msg = paste(length(unique(mydf$USUBJID)),
"patient(s) where DM data indicates death but no record indicating death in DS or AE. "),
data = mydf
)
}
}
}