Skip to content

Commit 9627618

Browse files
author
jwildfire
authored
Merge pull request #189 from ASA-DIA-InteractiveSafetyGraphics/dev-v0.9.0
v0.9.0
2 parents e5811aa + 6fa5f87 commit 9627618

40 files changed

+801
-720
lines changed

DESCRIPTION

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: safetyGraphics
22
Title: Create Interactive Graphics Related to Clinical Trial Safety
3-
Version: 0.8.1
3+
Version: 0.9.0
44
Authors@R: c(
55
person("Jeremy", "Wildfire", email = "jeremy_wildfire@rhoworld.com", role = c("cre","aut")),
66
person("Becca", "Krouse", role="aut"),
@@ -35,5 +35,7 @@ Imports:
3535
rmarkdown,
3636
rlang,
3737
tibble,
38-
utils
38+
utils,
39+
haven,
40+
shinyWidgets
3941
VignetteBuilder: knitr

NAMESPACE

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import(rmarkdown)
1616
import(shinyjs)
1717
importFrom(dplyr,"filter")
1818
importFrom(dplyr,filter)
19+
importFrom(haven,read_sas)
1920
importFrom(magrittr,"%>%")
2021
importFrom(purrr,keep)
2122
importFrom(purrr,map)
@@ -25,6 +26,7 @@ importFrom(purrr,map_lgl)
2526
importFrom(rlang,.data)
2627
importFrom(rlang,parse_expr)
2728
importFrom(shiny,runApp)
29+
importFrom(shinyWidgets,materialSwitch)
2830
importFrom(stringr,str_detect)
2931
importFrom(stringr,str_split)
3032
importFrom(stringr,str_subset)

R/detectStandard.R

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
#' Detect the data standard used for a data set
22
#'
3-
#' This function attempts to detect the data CDISC clinical standard used in a given R data frame.
3+
#' This function attempts to detect the clinical data standard used in a given R data frame.
44
#'
5-
#' This function compares the columns in the provided \code{"data"} with the required columns for a given data standard/domain combination. The function is designed to work with the SDTM and AdAM CDISC(<https://www.cdisc.org/>) standards for clinical trial data. Currently, "labs" is the only domain supported.
5+
#' This function compares the columns in the provided \code{"data"} with the required columns for a given data standard/domain combination. The function is designed to work with the SDTM and AdAM CDISC(<https://www.cdisc.org/>) standards for clinical trial data by default. Additional standards can be added by modifying the \code{"standardMetadata"} data set included as part of this package. Currently, "labs" is the only domain supported.
66
#'
77
#' @param data A data frame in which to detect the data standard
88
#' @param includeFields specifies whether to check the data set for field level data in addition to columns. Default: \code{TRUE}.
99
#' @param domain The data domain for the data set provided. Default: \code{"labs"}.
10-
#' @return A list containing the matching \code{"standard"} ("ADaM", "SDTM" or "None") and a list of \code{"details"} describing each standard considered.
10+
#' @return A list containing the matching \code{"standard"} from \code{"standardMetadata"} and a list of \code{"details"} describing each standard considered.
1111
#' @examples
1212

13-
#' detectStandard(adlbc)[["standard"]] #AdAM
13+
#' detectStandard(adlbc)[["standard"]] #adam
1414
#' detectStandard(iris)[["standard"]] #none
1515
#'
1616
#' \dontrun{
@@ -26,28 +26,45 @@ detectStandard <- function(data, includeFields=TRUE, domain="labs"){
2626
)
2727

2828

29-
# Create placeholder list, with Standard = None.
29+
# Create placeholder list, with Standard = none.
30+
available_standards <- safetyGraphics::standardsMetadata %>% select(-.data$text_key) %>% names
3031
standard_list <- list()
3132
standard_list[["details"]] = list()
32-
standard_list[["details"]][["ADaM"]]<-evaluateStandard(data,standard="ADaM", includeFields=includeFields, domain=domain)
33-
standard_list[["details"]][["SDTM"]]<-evaluateStandard(data,standard="SDTM", includeFields=includeFields, domain=domain)
33+
standard_list[["standard"]] = "none"
34+
standard_list[["standard_percent"]] = 0
35+
36+
for(standard in available_standards){
37+
# evaluate the current standard and save the result
38+
standard_list[["details"]][[standard]]<-evaluateStandard(data,standard=standard, includeFields=includeFields, domain=domain)
39+
40+
# if the current standard is a better match, use it as the overall standard
41+
# if there is a tie, don't change the standard - this means the column order in standardMetadata breaks ties!
42+
current_percent <- standard_list[["details"]][[standard]][["match_percent"]]
43+
overall_percent <- standard_list[["standard_percent"]]
44+
if(current_percent > overall_percent){
45+
standard_list[["standard"]] <- standard
46+
standard_list[["standard_percent"]] <- current_percent
47+
}
48+
}
3449

3550
# Determine the final standard
36-
if(standard_list[["details"]][["SDTM"]][["match"]] == "Full"){
37-
standard_list[["standard"]]<- "SDTM"
38-
} else if(standard_list[["details"]][["ADaM"]][["match"]] == "Full"){
39-
standard_list[["standard"]]<- "ADaM"
40-
} else if(standard_list[["details"]][["SDTM"]][["match"]] == "Partial" |
41-
standard_list[["details"]][["ADaM"]][["match"]] == "Partial"){
42-
standard_list[["standard"]] <- ifelse(
43-
length(standard_list[["details"]][["ADaM"]][["valid_count"]]) >
44-
length(standard_list[["details"]][["SDTM"]][["valid_count"]]),
45-
"ADaM" , "SDTM" #SDTM if they are equal
46-
)
47-
48-
} else {
49-
standard_list[["standard"]]<-"None"
50-
}
51+
52+
# TODO: write a general algorithm to do this ...
53+
# if(standard_list[["details"]][["sdtm"]][["match"]] == "Full"){
54+
# standard_list[["standard"]]<- "sdtm"
55+
# } else if(standard_list[["details"]][["adam"]][["match"]] == "Full"){
56+
# standard_list[["standard"]]<- "adam"
57+
# } else if(standard_list[["details"]][["sdtm"]][["match"]] == "Partial" |
58+
# standard_list[["details"]][["adam"]][["match"]] == "Partial"){
59+
# standard_list[["standard"]] <- ifelse(
60+
# length(standard_list[["details"]][["adam"]][["valid_count"]]) >
61+
# length(standard_list[["details"]][["sdtm"]][["valid_count"]]),
62+
# "adam" , "sdtm" #SDTM if they are equal
63+
# )
64+
#
65+
# } else {
66+
# standard_list[["standard"]]<-"None"
67+
# }
5168

5269
return(standard_list)
5370
}

R/evaluateStandard.R

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#' @param includeFields should field level data be evaluated?
88
#' @param domain data domain. "labs" only for now.
99
#'
10-
#' @return a list describing to what degree the data set matches the data standard. The "match" property describes compliance with the standard as "Full", "Partial" or "None". The "checks" property is a list of the data elements expected for the standard and whether they are "valid" in the given data set. "valid_checks" and "invalid_checks" provide counts of the specified checks.
10+
#' @return a list describing to what degree the data set matches the data standard. The "match" property describes compliance with the standard as "full", "partial" or "none". The "checks" property is a list of the data elements expected for the standard and whether they are "valid" in the given data set. "total_checks", "valid_checks" and "invalid_checks" provide counts of the specified checks. "match_percent" is calculated as valid_checks/total_checks.
1111
#'
1212
#' @examples
1313
#' safetyGraphics:::evaluateStandard(data=adlbc, standard="adam") # Match is TRUE
@@ -26,8 +26,7 @@ evaluateStandard <- function(data, standard, includeFields=TRUE, domain="labs"){
2626
is.data.frame(data),
2727
is.character(standard),
2828
is.logical(includeFields),
29-
is.character(domain),
30-
tolower(standard) %in% c("adam","sdtm")
29+
is.character(domain)
3130
)
3231

3332
standard<-tolower(standard)
@@ -43,7 +42,8 @@ evaluateStandard <- function(data, standard, includeFields=TRUE, domain="labs"){
4342
mutate(type = ifelse(.data$column_mapping, "column", "field")) %>%
4443
rowwise %>%
4544
mutate(field_column_name = ifelse(.data$field_mapping, getSettingsMetadata(cols=standard, text_keys=.data$field_column_key),"")) %>%
46-
mutate(valid = ifelse(.data$column_mapping,
45+
mutate(
46+
valid = ifelse(.data$column_mapping,
4747
hasColumn(data=data, columnName=.data$standard_val),
4848
hasField(data=data, columnName=.data$field_column_name, fieldValue=.data$standard_val)
4949
)) %>%
@@ -54,20 +54,20 @@ evaluateStandard <- function(data, standard, includeFields=TRUE, domain="labs"){
5454
standardChecks <- standardChecks %>% filter(.data$type != "field")
5555
}
5656

57-
# compare_summary[["checks"]] <- split(standardChecks, seq(nrow(standardChecks)))%>%map(~as.list(.)) #coerce to list of lists?
58-
compare_summary[["checks"]] <- standardChecks #or just keep the tibble ...
57+
compare_summary[["checks"]] <- standardChecks
5958

6059
# count valid/invalid data elements
60+
compare_summary[["total_count"]] <- standardChecks %>% nrow()
6161
compare_summary[["valid_count"]] <- standardChecks %>% filter(.data$valid) %>% nrow()
6262
compare_summary[["invalid_count"]] <- standardChecks %>% filter(!.data$valid) %>% nrow()
63-
64-
63+
compare_summary[["match_percent"]] <- compare_summary[["valid_count"]] / compare_summary[["total_count"]]
64+
6565
if (compare_summary[["invalid_count"]]==0) {
66-
compare_summary[["match"]] <- "Full"
66+
compare_summary[["match"]] <- "full"
6767
} else if(compare_summary[["valid_count"]]>0) {
68-
compare_summary[["match"]] <- "Partial"
68+
compare_summary[["match"]] <- "partial"
6969
} else {
70-
compare_summary[["match"]] <- "None"
70+
compare_summary[["match"]] <- "none"
7171
}
7272

7373
return(compare_summary)

R/getSettingsMetadata.R

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#' @param charts optional vector of chart names used to filter the metadata. Exact matches only (case-insensitive). All rows returned by default.
66
#' @param text_keys optional vector of keys used to filter the metadata. Partial matches for any of the strings are returned (case-insensitive). All rows returned by default.
77
#' @param filter_expr optional filter expression used to subset the data.
8+
#' @param add_standards should data standard info stored in standardsMetadata be included
89
#' @param cols optional vector of columns to return from the metadata. All columns returned by default.
910
#' @param metadata metadata data frame to be queried
1011
#'
@@ -27,9 +28,15 @@
2728
#'
2829
#' @export
2930

30-
getSettingsMetadata<-function(charts=NULL, text_keys=NULL, cols=NULL, filter_expr=NULL, metadata = safetyGraphics::settingsMetadata){
31+
getSettingsMetadata<-function(charts=NULL, text_keys=NULL, cols=NULL, filter_expr=NULL, add_standards=TRUE, metadata = safetyGraphics::settingsMetadata){
3132

32-
md <- metadata
33+
md <- metadata %>% mutate(text_key=as.character(.data$text_key))
34+
35+
if(add_standards){
36+
ms<-safetyGraphics::standardsMetadata %>% mutate(text_key=as.character(.data$text_key))
37+
md<-md%>%left_join(ms, by="text_key")
38+
}
39+
3340
all_columns <- names(md)
3441

3542
#filter the metadata based on the charts option (if any)

R/safetyGraphicsApp.R

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,16 @@
99
#' @importFrom purrr map keep
1010
#' @importFrom magrittr "%>%"
1111
#' @import rmarkdown
12+
#' @importFrom haven read_sas
13+
#' @importFrom shinyWidgets materialSwitch
1214
#'
1315
#' @export
1416
#'
15-
safetyGraphicsApp <- function(maxFileSize = 20) {
17+
safetyGraphicsApp <- function(maxFileSize = NULL) {
1618
#increase maximum file upload limit
17-
options(shiny.maxRequestSize=(maxFileSize*1024^2))
19+
if(!is.null(maxFileSize)){
20+
options(shiny.maxRequestSize=(maxFileSize*1024^2))
21+
}
1822

1923
path <- system.file("eDISH_app", package = "safetyGraphics")
2024
shiny::runApp(path, launch.browser = TRUE)

R/settingsMetadata.R

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@
1414
#' \item{column_type}{Expected type for the data column values. Should be "character","logical" or "numeric"}
1515
#' \item{field_mapping}{Flag indicating whether the setting corresponds to a field-level mapping in the data}
1616
#' \item{field_column_key}{Key for the column that provides options for the field-level mapping in the data}
17-
#' \item{adam}{Settings values for the ADaM standard}
18-
#' \item{sdtm}{Settings values for the SDTM standard}
17+
#' \item{setting_cat}{Setting category (data, measure, appearance)}
1918
#' }
2019
#'
2120
#' @source Created for this package

R/standardsMetadata.R

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#' Standards Metadata
2+
#'
3+
#' Metadata about the data standards used to configure safetyGraphics charts. One record per unique setting. Columns contain default setting values for clinical data standards, like the CDISC "adam" and "sdtm" standards.
4+
#'
5+
#' @format A data frame with 25 rows and 3 columns
6+
#' \describe{
7+
#' \item{text_key}{Text key indicating the setting name. \code{'--'} delimiter indicates a nested setting}
8+
#' \item{adam}{Settings values for the ADaM standard}
9+
#' \item{sdtm}{Settings values for the SDTM standard}
10+
#' }
11+
#'
12+
#' @source Created for this package
13+
"standardsMetadata"

data-raw/csv_to_rda.R

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,8 @@ library(usethis)
33
ablbc <- read.csv("data-raw/adlbc.csv")
44
usethis::use_data(adlbc, overwrite = TRUE)
55

6-
settingsMetadata<- read.csv("data-raw/settingsMetadata.csv")
6+
settingsMetadata <- read.csv("data-raw/settingsMetadata.csv")
77
usethis::use_data(settingsMetadata, overwrite = TRUE)
8+
9+
standardsMetadata <- read.csv("data-raw/standardsMetadata.csv")
10+
usethis::use_data(standardsMetadata, overwrite = TRUE)

0 commit comments

Comments
 (0)