Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Main PR #427

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: sdtmchecks
Title: Data Quality Checks for Study Data Tabulation Model (SDTM) Datasets
Version: 1.0.0
Version: 1.0.0.01
Authors@R: c(
person(given="Will",
family="Harris",
Expand Down
7 changes: 7 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# sdtmchecks 1.0.0.01 "CRAN Try"

## Refinements of existing data check functions

* Updates to several ophthalmology related checks


# sdtmchecks 1.0.0 "CRAN Try"


Expand Down
32 changes: 25 additions & 7 deletions R/check_cm_cmlat.R
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,32 @@ check_cm_cmlat <- function(CM,preproc = identity,...) {

mydf = CM %>%
filter(CMCAT == "CONCOMITANT MEDICATIONS") %>%
mutate(MISFLAG = ifelse((toupper(CMROUTE) %in% c("OPHTHALMIC", "INTRAVITREAL", "INTRAOCULAR",
"CONJUNCTIVAL", "INTRACAMERAL", "INTRACORNEAL",
"RETROBULBAR", "SUBTENON", "SUBRETINAL",
"SUBCONJUNCTIVAL") &
mutate(MISFLAG = ifelse((toupper(CMROUTE) %in% c("CONJUNCTIVAL",
"INTRACAMERAL",
"INTRACORNEAL",
"INTRAOCULAR",
"INTRAVITREAL",
"INTRAVITREAL VIA OCULAR IMPLANT",
"OPHTHALMIC",
"RETROBULBAR",
"SUBCONJUNCTIVAL",
"SUBRETINAL",
"SUBTENON",
"SUPRACHOROIDAL",
"TOPICAL") &
!(toupper(CMLAT) %in% c("LEFT", "RIGHT", "BILATERAL"))) |
(!(toupper(CMROUTE) %in% c("OPHTHALMIC", "INTRAVITREAL", "INTRAOCULAR",
"CONJUNCTIVAL", "INTRACAMERAL", "INTRACORNEAL",
"RETROBULBAR", "SUBTENON", "SUBRETINAL",
(!(toupper(CMROUTE) %in% c("CONJUNCTIVAL",
"INTRACAMERAL",
"INTRACORNEAL",
"INTRAOCULAR",
"INTRAVITREAL",
"INTRAVITREAL VIA OCULAR IMPLANT",
"OPHTHALMIC",
"RETROBULBAR",
"SUBCONJUNCTIVAL",
"SUBRETINAL",
"SUBTENON",
"SUPRACHOROIDAL",
"TOPICAL")) &
(toupper(CMLAT) %in% c("LEFT", "RIGHT", "BILATERAL"))), 1, 0))

Expand Down
24 changes: 12 additions & 12 deletions R/check_ec_sc_lat.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
#' assuming drug administration is collected for study eye only.
#' 2.> Subset Subject Characteristics dataset (SC) for only Study Eye Selection
#' 3.> Compare Exposure dataset laterality (EC.ECLAT) with Subject Characteristics dataset laterality
#' (SC.SCORRES - OS = LEFT, OD = RIGHT) and report if there is any mismatch.
#' (SC.SCSTRESC - OS = LEFT, OD = RIGHT) and report if there is any mismatch.
#'
#' @param SC Subject Characteristics Dataset for Ophtha Study with variables
#' USUBJID, SCTEST, SCTESTCD, SCCAT, SCORRES, SCDTC
#' USUBJID, SCTEST, SCTESTCD, SCCAT, SCSTRESC, SCDTC
#' @param EC Subject Exposure Dataset with variables
#' USUBJID, ECCAT (if available), ECLOC, ECMOOD, ECLAT, ECSTDY, VISIT, ECSTDTC, ECOCCUR, ECROUTE
#'
Expand All @@ -34,7 +34,7 @@
#' SCTESTCD = c("ELIGEYE", "FOCID", "", "ELIGEYE", "FOCID", ""),
#' SCCAT = c("STUDY EYE SELECTION", "STUDY EYE SELECTION", "",
#' "STUDY EYE SELECTION", "STUDY EYE SELECTION", ""),
#' SCORRES = c("LEFT", "OS", "", "RIGHT", "OD", ""),
#' SCSTRESC = c("LEFT", "OS", "", "RIGHT", "OD", ""),
#' SCDTC = "2021-01-01",
#' stringsAsFactors = FALSE)
#'
Expand Down Expand Up @@ -67,7 +67,7 @@
#' SCTESTCD = c("ELIGEYE", "FOCID", "", "ELIGEYE", "FOCID", ""),
#' SCCAT = c("STUDY EYE SELECTION", "STUDY EYE SELECTION", "",
#' "STUDY EYE SELECTION", "STUDY EYE SELECTION", ""),
#' SCORRES = c("LEFT", "OS", "", "RIGHT", "OD", ""),
#' SCSTRESC = c("LEFT", "OS", "", "RIGHT", "OD", ""),
#' SCDTC = "2021-01-01",
#' stringsAsFactors = FALSE)
#'
Expand Down Expand Up @@ -102,7 +102,7 @@
#' SCCAT = c("STUDY EYE SELECTION", "STUDY EYE SELECTION", "",
#' "STUDY EYE SELECTION",
#' "STUDY EYE SELECTION", "", "STUDY EYE SELECTION"),
#' SCORRES = c("LEFT", "OS", "", "RIGHT", "OD", "", "RIGHT"),
#' SCSTRESC = c("LEFT", "OS", "", "RIGHT", "OD", "", "RIGHT"),
#' SCDTC = "2021-01-01",
#' stringsAsFactors = FALSE)
#'
Expand All @@ -127,9 +127,9 @@

check_ec_sc_lat <- function(EC,SC) {

if (SC %lacks_any% c("USUBJID", "SCTEST", "SCTESTCD", "SCCAT", "SCORRES", "SCDTC")) {
if (SC %lacks_any% c("USUBJID", "SCTEST", "SCTESTCD", "SCCAT", "SCSTRESC", "SCDTC")) {

fail(lacks_msg(SC, c("USUBJID","SCTEST","SCTESTCD","SCCAT","SCORRES", "SCDTC")))
fail(lacks_msg(SC, c("USUBJID","SCTEST","SCTESTCD","SCCAT","SCSTRESC", "SCDTC")))

}

Expand Down Expand Up @@ -164,13 +164,13 @@ check_ec_sc_lat <- function(EC,SC) {
}

# Subset SC data on SC.SCCAT = "STUDY EYE SELECTION", and
# SCTESTCD = "FOCID". SC.SCORRES OS (oculus sinister) means the left
# SCTESTCD = "FOCID". SC.SCSTRESC OS (oculus sinister) means the left
# eye and OD (oculus dextrus) means the right eye.
SC <- SC %>%
select(USUBJID, SCTESTCD, SCTEST, SCCAT, SCORRES, SCDTC) %>%
select(USUBJID, SCTESTCD, SCTEST, SCCAT, SCSTRESC, SCDTC) %>%
filter(toupper(SCTESTCD) == "FOCID") %>%
mutate(SC_STUDYEYE = ifelse(toupper(SCORRES) == "OS", "LEFT",
ifelse(toupper(SCORRES) == "OD", "RIGHT","SCORRES Value not OS or OD")))
mutate(SC_STUDYEYE = ifelse(toupper(SCSTRESC) == "OS", "LEFT",
ifelse(toupper(SCSTRESC) == "OD", "RIGHT","SCSTRESC Value not OS or OD")))

# Subset EC data on EC.ECCAT (if available) remove Fellow Eye Records,
# EC.ECMOOD = "PERFORMED" EC.ECOCCUR = "Y"
Expand All @@ -197,7 +197,7 @@ check_ec_sc_lat <- function(EC,SC) {

mydf = mydf1 %>% filter(MISFLAG == 1)%>%
filter(ECROUTE != "NON-OCULAR ROUTE" | is.na(ECROUTE)) %>%
select(-MISFLAG, -SCTESTCD, -SCTEST, -SCCAT, -ECLOC, -ECMOOD, -ECOCCUR, -SCORRES)
select(-MISFLAG, -SCTESTCD, -SCTEST, -SCCAT, -ECLOC, -ECMOOD, -ECOCCUR, -SCSTRESC)

if ((nrow(mydf) > 0 ) == FALSE) {
pass()
Expand Down
22 changes: 11 additions & 11 deletions R/check_oe_sc_lat_count_fingers.R
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#' @description Check If Post Treatment Count Fingers in Study Eye is done on the actual Study eye by comparing laterality from OE domain with SC domain.
#' Check is ignored if Post Treatment Count Fingers is not collected in study as it is quite common for EP studies
#'
#' @param SC Subject Characteristics Dataset for Ophtho Study with variables USUBJID, SCTEST, SCTESTCD, SCCAT, SCORRES, SCDTC
#' @param SC Subject Characteristics Dataset for Ophtho Study with variables USUBJID, SCTEST, SCTESTCD, SCCAT, SCSTRESC, SCDTC
#' @param OE Ophthalmic Examination Dataset for Ophtho Study with variables USUBJID, OECAT, OELAT, VISIT, OEDTC, OETEST, OELOC, OESTAT (if present)
#'
#' @importFrom dplyr %>% filter mutate select
Expand All @@ -30,7 +30,7 @@
#' SCTESTCD = c("ELIGEYE", "FOCID", "", "ELIGEYE", "FOCID", ""),
#' SCCAT = c("STUDY EYE SELECTION", "STUDY EYE SELECTION", "",
#' "STUDY EYE SELECTION", "STUDY EYE SELECTION", ""),
#' SCORRES = c("LEFT", "OS", "", "RIGHT", "OD", ""),
#' SCSTRESC = c("LEFT", "OS", "", "RIGHT", "OD", ""),
#' SCDTC = rep("2021-01-01", 6),
#' stringsAsFactors = FALSE)
#'
Expand Down Expand Up @@ -60,7 +60,7 @@
#' SCTESTCD = c("ELIGEYE", "FOCID", "", "ELIGEYE", "FOCID", ""),
#' SCCAT = c("STUDY EYE SELECTION", "STUDY EYE SELECTION", "",
#' "STUDY EYE SELECTION", "STUDY EYE SELECTION", ""),
#' SCORRES = c("LEFT", "OS", "", "RIGHT", "OD", ""),
#' SCSTRESC = c("LEFT", "OS", "", "RIGHT", "OD", ""),
#' SCDTC = rep("2021-01-01", 6),
#' stringsAsFactors = FALSE)
#'
Expand Down Expand Up @@ -93,7 +93,7 @@
#' SCCAT = c("STUDY EYE SELECTION", "STUDY EYE SELECTION", "",
#' "STUDY EYE SELECTION", "STUDY EYE SELECTION",
#' "", "STUDY EYE SELECTION"),
#' SCORRES = c("LEFT", "OS", "", "RIGHT", "OD", "", "OS"),
#' SCSTRESC = c("LEFT", "OS", "", "RIGHT", "OD", "", "OS"),
#' SCDTC = "2021-01-01",
#' stringsAsFactors = FALSE)
#'
Expand All @@ -119,9 +119,9 @@

check_oe_sc_lat_count_fingers <- function(OE, SC) {

if (SC %lacks_any% c("USUBJID", "SCTEST", "SCTESTCD", "SCCAT", "SCORRES", "SCDTC")) {
if (SC %lacks_any% c("USUBJID", "SCTEST", "SCTESTCD", "SCCAT", "SCSTRESC", "SCDTC")) {

fail(lacks_msg(SC, c("USUBJID","SCTEST","SCTESTCD","SCCAT","SCORRES", "SCDTC")))
fail(lacks_msg(SC, c("USUBJID","SCTEST","SCTESTCD","SCCAT","SCSTRESC", "SCDTC")))

}

Expand All @@ -138,12 +138,12 @@ check_oe_sc_lat_count_fingers <- function(OE, SC) {

else {

# Subset SC data on SC.SCCAT = "STUDY EYE SELECTION", and and SCTESTCD = "FOCID". SC.SCORRES OS (oculus sinister) means the left
# Subset SC data on SC.SCCAT = "STUDY EYE SELECTION", and and SCTESTCD = "FOCID". SC.SCSTRESC OS (oculus sinister) means the left
# eye and OD (oculus dextrus) means the right eye.
SC <- SC %>% select(USUBJID, SCTESTCD, SCTEST, SCCAT, SCORRES, SCDTC) %>%
SC <- SC %>% select(USUBJID, SCTESTCD, SCTEST, SCCAT, SCSTRESC, SCDTC) %>%
filter(SCTESTCD %in% c("FOCID")) %>%
mutate(SC_STUDYEYE = ifelse(SCORRES == "OS", "LEFT",
ifelse(SCORRES == "OD", "RIGHT", "SCORRES Value not OS or OD")))
mutate(SC_STUDYEYE = ifelse(SCSTRESC == "OS", "LEFT",
ifelse(SCSTRESC == "OD", "RIGHT", "SCSTRESC Value not OS or OD")))

# Remove OESTAT NOT DONE
if ((any(names(OE) == "OESTAT")) == TRUE) {
Expand All @@ -166,7 +166,7 @@ check_oe_sc_lat_count_fingers <- function(OE, SC) {
mydf1 <- left_join(SC, OE, by="USUBJID") %>%
mutate(MISFLAG = ifelse((toupper(SC_STUDYEYE) != toupper(OELAT)) | is.na(toupper(OELAT)), 1, 0))

mydf = mydf1 %>% filter(MISFLAG == 1) %>% select(-MISFLAG, -SCTESTCD, -SCTEST, -SCCAT, -SCORRES, -OELOC, -OECAT)
mydf = mydf1 %>% filter(MISFLAG == 1) %>% select(-MISFLAG, -SCTESTCD, -SCTEST, -SCCAT, -SCSTRESC, -OELOC, -OECAT)

if ((nrow(mydf) > 0 ) == FALSE) {
pass()
Expand Down
22 changes: 11 additions & 11 deletions R/check_sc_dm_eligcrit.R
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
#' @title Check SC Eye Meeting Eligibility Criteria assignments among DM patients
#'
#' @description Check if SC.SCCAT = "STUDY EYE SELECTION" and SC.SCTESTCD = "ELIGEYE",
#' then SC.SCORRES should have "OS", "OD", or "OU" values. Flag if subject is in
#' DM and without an associated SC.SCORRES value or the ELIGEYE Eye Meeting
#' then SC.SCSTRESC should have "OS", "OD", or "OU" values. Flag if subject is in
#' DM and without an associated SC.SCSTRESC value or the ELIGEYE Eye Meeting
#' Eligibility Criteria value is not "OS", "OD", or "OU".
#'
#' @param DM Subject Demographics SDTM dataset with variable USUBJID
#' @param SC Subject Characteristics SDTM dataset for Ophtho Study with variables
#' USUBJID, SCTESTCD, SCTEST, SCCAT, SCORRES, SCDTC
#' USUBJID, SCTESTCD, SCTEST, SCCAT, SCSTRESC, SCDTC
#'
#' @importFrom dplyr %>% filter mutate select left_join
#'
Expand Down Expand Up @@ -37,17 +37,17 @@
#' "STUDY EYE SELECTION",
#' "STUDY EYE SELECTION",
#' ""),
#' SCORRES = c("OS", "OS", "", "", "OU", ""),
#' SCSTRESC = c("OS", "OS", "", "", "OU", ""),
#' SCDTC = rep("2021-01-01", 6),
#' stringsAsFactors = FALSE)
#'
#' check_sc_dm_eligcrit(SC=sc, DM=dm)
#'
#' dm <- data.frame(USUBJID = c(1,2,3,4))
#' sc$SCORRES[4] = "OS"
#' sc$SCSTRESC[4] = "OS"
#' check_sc_dm_eligcrit(SC=sc, DM=dm)
#'
#' sc$SCORRES <- NULL
#' sc$SCSTRESC <- NULL
#' check_sc_dm_eligcrit(SC=sc, DM=dm)
#'
#'
Expand All @@ -61,22 +61,22 @@ check_sc_dm_eligcrit <- function(DM, SC) {

}

else if (SC %lacks_any% c("USUBJID", "SCTEST", "SCTESTCD", "SCCAT", "SCORRES", "SCDTC")) {
else if (SC %lacks_any% c("USUBJID", "SCTEST", "SCTESTCD", "SCCAT", "SCSTRESC", "SCDTC")) {

fail(lacks_msg(SC, c("USUBJID","SCTEST","SCTESTCD","SCCAT","SCORRES", "SCDTC")))
fail(lacks_msg(SC, c("USUBJID","SCTEST","SCTESTCD","SCCAT","SCSTRESC", "SCDTC")))
}

else {

DM = DM %>% select(USUBJID)

SC = SC %>% select(USUBJID, SCTESTCD, SCTEST, SCCAT, SCORRES, SCDTC) %>%
SC = SC %>% select(USUBJID, SCTESTCD, SCTEST, SCCAT, SCSTRESC, SCDTC) %>%
mutate(MISFLAG = ifelse((grepl("ELIGEYE", SCTESTCD, ignore.case=TRUE) == TRUE) &
(!(SCORRES %in% c("OD", "OS", "OU"))), 1, 0))
(!(SCSTRESC %in% c("OD", "OS", "OU"))), 1, 0))

mydf = left_join(DM, SC, by="USUBJID")

mydf = mydf %>% filter(MISFLAG == 1 | is.na(SCORRES)) %>% select(-MISFLAG)
mydf = mydf %>% filter(MISFLAG == 1 | is.na(SCSTRESC)) %>% select(-MISFLAG)

if ((nrow(mydf) > 0 ) == FALSE) {
pass()
Expand Down
22 changes: 11 additions & 11 deletions R/check_sc_dm_seyeselc.R
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
#' @title Check SC Study Eye Selection assignments among DM patients
#'
#' @description Check if SC.SCCAT = "STUDY EYE SELECTION" and SC.SCTESTCD = "FOCID",
#' then SC.SCORRES should have "OS", "OD", or "OU" values. Flag if subject is in
#' DM and without an associated SC.SCORRES value or the STUDY EYE SELECTION value
#' is not "OS", "OD", or "OU".
#' then SC.SCSTRESC should have "OS" or "OD" values. Flag if subject is in
#' DM and without an associated SC.SCSTRESC value or the STUDY EYE SELECTION value
#' is not "OS" or "OD".
#'
#' @param DM Subject Demographics SDTM dataset with variable USUBJID
#' @param SC Subject Characteristics SDTM dataset for Ophtho Study with variables
#' USUBJID, SCTESTCD, SCTEST, SCCAT, SCORRES, SCDTC
#' USUBJID, SCTESTCD, SCTEST, SCCAT, SCSTRESC, SCDTC
#'
#' @importFrom dplyr %>% filter mutate select
#'
Expand Down Expand Up @@ -36,7 +36,7 @@
#' "",
#' "STUDY EYE SELECTION",
#' "STUDY EYE SELECTION", ""),
#' SCORRES = c("LEFT", "OS", "", "RIGHT", "OD", ""),
#' SCSTRESC = c("LEFT", "OS", "", "RIGHT", "OD", ""),
#' SCDTC = rep("2021-01-01", 6),
#' stringsAsFactors = FALSE)
#'
Expand All @@ -56,7 +56,7 @@
#' "",
#' "STUDY EYE SELECTION",
#' "STUDY EYE SELECTION", ""),
#' SCORRES = c("LEFT", "OS", "", "RIGHT", "", ""),
#' SCSTRESC = c("LEFT", "OS", "", "RIGHT", "", ""),
#' SCDTC = rep("2021-01-01", 6),
#' stringsAsFactors = FALSE)
#'
Expand All @@ -73,22 +73,22 @@ check_sc_dm_seyeselc <- function(DM, SC) {

}

else if (SC %lacks_any% c("USUBJID", "SCTEST", "SCTESTCD", "SCCAT", "SCORRES", "SCDTC")) {
else if (SC %lacks_any% c("USUBJID", "SCTEST", "SCTESTCD", "SCCAT", "SCSTRESC", "SCDTC")) {

fail(lacks_msg(SC, c("USUBJID", "SCTEST", "SCTESTCD", "SCCAT", "SCORRES", "SCDTC")))
fail(lacks_msg(SC, c("USUBJID", "SCTEST", "SCTESTCD", "SCCAT", "SCSTRESC", "SCDTC")))
}

else {

DM = DM %>% select(USUBJID)

SC = SC %>% select(USUBJID, SCTESTCD, SCTEST, SCCAT, SCORRES, SCDTC) %>%
SC = SC %>% select(USUBJID, SCTESTCD, SCTEST, SCCAT, SCSTRESC, SCDTC) %>%
mutate(MISFLAG = ifelse((grepl("FOCID", SCTESTCD, ignore.case=TRUE) == TRUE) &
(!(SCORRES %in% c("OD", "OS"))), 1, 0))
(!(SCSTRESC %in% c("OD", "OS"))), 1, 0))

mydf = left_join(DM, SC, by="USUBJID")

mydf = mydf %>% filter(MISFLAG == 1 | is.na(SCORRES)) %>% select(-MISFLAG)
mydf = mydf %>% filter(MISFLAG == 1 | is.na(SCSTRESC)) %>% select(-MISFLAG)

if ((nrow(mydf) > 0 ) == FALSE) {
pass()
Expand Down
2 changes: 1 addition & 1 deletion R/globals.R
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ utils::globalVariables(c(
"OESTRESN.y","OETESTCD","OETSTDTL","PARTB_CONST","PRCAT","PRENDTC","PRLAT","PROCCUR",
"PRPRESP","PRSTDTC","QSCAT","QSDTC","QSDTC1","QSORRES","QSREASND","QSSTAT","QSSTRESC",
"QSTESTCD","RAVE","REFTERM","ROW","ROWNUM","RSDTC","RSEVAL","RSORRES","RSSTAT","SCCAT","SCDTC",
"SCORRES","SCTEST","SCTESTCD","SC_STUDYEYE","SITEID","SSDTC","SSORRES","SSSTAT","SYSBP",
"SCORRES", "SCSTRESC", "SCTEST","SCTESTCD","SC_STUDYEYE","SITEID","SSDTC","SSORRES","SSSTAT","SYSBP",
"TOTAL","TOT_1M","TOT_4M","TRDTC","TREVAL","TRTESTCD","TSPARMCD","TSVAL","TUDTC","TUEVAL",
"TULOC","TUORRES","USUBJID","VISIT","VISITNUM","VSDTC","VSDTC.SYSBP","VSORRES","VSSPID",
"VSSTRESN","VSTEST","VSTESTCD","Var1","Var2","check_stat","icdate","issue",
Expand Down
Loading
Loading