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

shinyvalidate improvements #199

Merged
merged 78 commits into from
Jan 3, 2023
Merged
Show file tree
Hide file tree
Changes from 61 commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
bc13fa9
add function gather_fails
Nov 28, 2022
7473a83
gather_fails in tm_g_a_oview
Nov 28, 2022
07dc66e
update examples
Nov 29, 2022
f589883
replace validate with shinyvalidate
Nov 29, 2022
3e7e800
use validations in tm_g_ae_sub
Nov 29, 2022
3d80d64
use validations in tm_g_butterfly
Nov 29, 2022
c77cbb6
use validations in tm_g_events_ternm_id
Nov 29, 2022
d803659
use validations in tm_g_spiderplot
Nov 29, 2022
cedcbb5
use validations in tm_g_swimlane
Nov 29, 2022
2917c8b
use validations in tm_g_waterfall
Nov 29, 2022
de1c988
minor edits
Nov 29, 2022
976252c
use validations in tm_g_heat_bygrade
Nov 30, 2022
fc1bfcf
use validations in tm_g_patient_profile
Nov 30, 2022
dad8481
fix validations of selected values
Nov 30, 2022
b29540c
apply review and clean up
Dec 1, 2022
b6b54f5
add namespace prefixes for gather_fails
Dec 1, 2022
b2ee629
move gather_fails to teal package
Dec 1, 2022
3380b6b
update DESCRIPTION
Dec 1, 2022
3250430
update NEWS
Dec 7, 2022
78a7203
changed 'gather_fails' to 'validate_inputs'
Dec 7, 2022
a509412
Merge 78a7203100605a85e60ce414a5afdeef697d979d into f07ee20511a66e052…
chlebowa Dec 7, 2022
221b250
[skip actions] Restyle files
github-actions[bot] Dec 7, 2022
cb9d781
trigger
Dec 8, 2022
133bbe1
apply code review
Dec 8, 2022
1f63bf4
update DESCRIPTION
Dec 8, 2022
f667bac
add workflow badges to README
Dec 9, 2022
21b6b43
update code review
Dec 9, 2022
2c1052e
Merge 21b6b439ba057b0936121908dd934057b4a57efc into f07ee20511a66e052…
chlebowa Dec 9, 2022
a7608a1
[skip actions] Restyle files
github-actions[bot] Dec 9, 2022
905d4f8
rework patient_profile module
Dec 9, 2022
2e18889
Merge 905d4f86d50a0f8a34937b9e4298410d79de65bf into f07ee20511a66e052…
chlebowa Dec 9, 2022
9f1de3e
[skip actions] Restyle files
github-actions[bot] Dec 9, 2022
0512830
adjust patient_profile module
Dec 9, 2022
2f7580b
Merge 05128304c53cad3cae9ce348f25d520086a0e837 into f07ee20511a66e052…
chlebowa Dec 9, 2022
fa5bf0a
[skip actions] Restyle files
github-actions[bot] Dec 9, 2022
ba68b65
trigger
Dec 9, 2022
980b4a2
move ivs to reactives, fix bugs
Dec 12, 2022
f46296b
amend DEWSCRIPTION and NEWS
Dec 12, 2022
385cbc0
Merge branch 'main' into 185_gather_fails@main
chlebowa Dec 12, 2022
337a0bb
Merge 385cbc0d6bf0c8783664458089763e6eba80f6b0 into 531c64f03499b10e1…
chlebowa Dec 12, 2022
2e0d4ea
[skip actions] Restyle files
github-actions[bot] Dec 12, 2022
dbd52a3
apply code review
Dec 14, 2022
127d9a2
apply more code review
Dec 14, 2022
532b4c7
linter
Dec 14, 2022
a448b02
more review of patient_profile
Dec 14, 2022
9bbf16e
apply review of ~heat_bygrade
Dec 14, 2022
bb06f3c
apply review to spiderplot
Dec 14, 2022
24eb0f1
more review patient_profile
Dec 14, 2022
54706cf
Merge 24eb0f11aade9f5f36a52fc692c7a2391ff47f49 into 531c64f03499b10e1…
chlebowa Dec 14, 2022
8295598
[skip actions] Restyle files
github-actions[bot] Dec 14, 2022
ded2d75
update NEWS
Dec 14, 2022
6e069b7
Move checkbox init to UI
gogonzo Dec 15, 2022
9103936
fix calls
gogonzo Dec 15, 2022
0018423
Merge 9103936031492fa18239a64c5dec71a0af9ff436 into 531c64f03499b10e1…
chlebowa Dec 15, 2022
94cd612
[skip actions] Restyle files
github-actions[bot] Dec 15, 2022
6f8f767
Fixing sl_dataname in the g_patient_profile call
gogonzo Dec 15, 2022
64c9687
Merge branch '185_gather_fails@main' of github.com:insightsengineerin…
gogonzo Dec 15, 2022
bfe2d76
fix
gogonzo Dec 15, 2022
fdefc39
fix
gogonzo Dec 15, 2022
4c675ed
fix heat_by_grade and reload docs
gogonzo Dec 15, 2022
14738f4
fix checkboxes error
gogonzo Dec 15, 2022
dac01ad
fix example
Dec 21, 2022
adb5b68
indentation
Dec 21, 2022
1080a54
add debouce to plot in patient_profile
Dec 21, 2022
52b9b5e
add debouce to plot in heat_bygrade
Dec 21, 2022
27b19dd
add validation to heat_bygrade
Dec 21, 2022
74c5da4
move debounce in patient_profile
Dec 21, 2022
4fd69ce
update validation in events_term_id
Dec 21, 2022
800ccf7
add debounce in butterfly
Dec 21, 2022
82f7c80
add debounce in ae_sub
Dec 21, 2022
56416fa
add debounce in ae_oview
Dec 21, 2022
650f8f6
Merge 56416fadac040a067a31a106f18e718de86e557e into 531c64f03499b10e1…
chlebowa Dec 21, 2022
aeb6563
[skip actions] Restyle files
github-actions[bot] Dec 21, 2022
5d71863
trigger
Dec 21, 2022
0ae47bc
bug fix and NEWS update
Dec 22, 2022
65a1daf
[skip actions] Roxygen Man Pages Auto Update
dependabot-preview[bot] Dec 22, 2022
146305c
trigger checks
Jan 3, 2023
83e2354
trigger checks again
Jan 3, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,14 @@ Depends:
osprey (>= 0.1.15),
R (>= 3.6),
shiny,
teal (>= 0.12.0)
teal (>= 0.12.0.9013)
Imports:
checkmate,
dplyr,
formatters (>= 0.3.1),
ggplot2,
lifecycle,
logger (>= 0.2.0),
purrr,
shinyvalidate,
teal.code (>= 0.2.0),
teal.logger (>= 0.1.1),
Expand Down Expand Up @@ -65,4 +64,4 @@ Encoding: UTF-8
Language: en-US
LazyData: true
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.2.1
RoxygenNote: 7.2.2
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
* Examples now use `scda.2022` instead of `scda.2021`.
* Fixed crash in `tm_g_heat_bygrade` when not plotting `Conmed`.
* Added validation to `tm_g_spiderplot.R` that checks if there are duplicates in X and Y facet variables.
* Improved input validation and used the `teal::validate_inputs` mechanism to send validation messages to the output panel.
* Removed `purrr` from dependencies.
* Removed redundant formal arguments from add added argument checks to `tm_g_patient_profile`.
chlebowa marked this conversation as resolved.
Show resolved Hide resolved

### Breaking changes

Expand Down
73 changes: 39 additions & 34 deletions R/tm_g_ae_oview.R
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,10 @@ tm_g_ae_oview <- function(label,
)
)
checkmate::assert_numeric(plot_height, len = 3, any.missing = FALSE, finite = TRUE)
checkmate::assert_numeric(plot_height[1], lower = plot_height[2], upper = plot_height[3], .var.name = "plot_height")
checkmate::assert_numeric(plot_height[1],
lower = plot_height[2], upper = plot_height[3],
.var.name = "plot_height"
)
checkmate::assert_numeric(plot_width, len = 3, any.missing = FALSE, null.ok = TRUE, finite = TRUE)
checkmate::assert_numeric(
plot_width[1],
Expand Down Expand Up @@ -232,14 +235,35 @@ srv_g_ae_oview <- function(id,
checkmate::assert_class(data, "tdata")

moduleServer(id, function(input, output, session) {
iv <- shinyvalidate::InputValidator$new()
iv$add_rule("arm_var", shinyvalidate::sv_required())
iv$add_rule("flag_var_anl", shinyvalidate::sv_required(
message = "Please select at least one flag"
))
iv$enable()
iv <- reactive({
ANL <- data[[dataname]]() # nolint

iv <- shinyvalidate::InputValidator$new()
iv$add_rule("arm_var", shinyvalidate::sv_required(
message = "Arm Variable is required"
))
iv$add_rule("arm_var", ~ if (!is.factor(ANL[[.]])) {
"Arm Var must be a factor variable"
})
iv$add_rule("arm_var", ~ if (nlevels(ANL[[.]]) < 2L) {
"Selected Arm Var must have at least two levels"
})
iv$add_rule("flag_var_anl", shinyvalidate::sv_required(
message = "At least one Flag is required"
))
rule_diff <- function(value, other) {
if (isTRUE(value == other)) "Control and Treatment must be different"
}
iv$add_rule("arm_trt", rule_diff, other = input$arm_ref)
iv$add_rule("arm_ref", rule_diff, other = input$arm_trt)
iv$enable()
iv
})

decorate_output <- srv_g_decorate(id = NULL, plt = plot_r, plot_height = plot_height, plot_width = plot_width)
decorate_output <- srv_g_decorate(
id = NULL, plt = plot_r,
plot_height = plot_height, plot_width = plot_width
)
font_size <- decorate_output$font_size
pws <- decorate_output$pws

Expand Down Expand Up @@ -285,34 +309,15 @@ srv_g_ae_oview <- function(id,

output_q <- reactive({
ANL <- data[[dataname]]() # nolint
validate(need(iv$is_valid(), "Misspecification error: please observe red flags in the encodings."))

teal::validate_has_data(ANL, min_nrow = 10, msg = sprintf("%s has not enough data", dataname))

teal::validate_inputs(iv())

validate(need(
is.factor(ANL[[input$arm_var]]),
"Selected arm variable needs to be a factor."
))
validate(need(input$flag_var_anl, "Please select at least one flag."))
iv_comp <- shinyvalidate::InputValidator$new()
iv_comp$add_rule("arm_trt", shinyvalidate::sv_not_equal(
input$arm_ref,
message_fmt = "Must not be equal to Control"
input$arm_trt %in% ANL[[input$arm_var]] && input$arm_ref %in% ANL[[input$arm_var]],
"Treatment or Control not found in Arm Variable. Perhaps they have been filtered out?"
))
iv_comp$add_rule("arm_ref", shinyvalidate::sv_not_equal(
input$arm_trt,
message_fmt = "Must not be equal to Treatment"
))
iv_comp$enable()

validate(need(iv_comp$is_valid(), "Misspecification error: please observe red flags in the encodings."))
validate(need(nlevels(ANL[[input$arm_var]]) > 1, "Arm needs to have at least 2 levels"))
validate_has_data(ANL, min_nrow = 10)
if (all(c(input$arm_trt, input$arm_ref) %in% ANL[[input$arm_var]])) {
iv_an <- shinyvalidate::InputValidator$new()
iv_an$add_rule("arm_ref", shinyvalidate::sv_in_set(set = ANL[[input$arm_var]]))
iv_an$add_rule("arm_trt", shinyvalidate::sv_in_set(set = ANL[[input$arm_var]]))
iv_an$enable()
validate(need(iv_an$is_valid(), "Misspecification error: please observe red flags in the encodings."))
}
validate(need(all(c(input$arm_trt, input$arm_ref) %in% unique(ANL[[input$arm_var]])), "Plot loading"))

q1 <- teal.code::eval_code(
teal.code::new_qenv(tdata2env(data), code = get_code_tdata(data)),
Expand Down
67 changes: 33 additions & 34 deletions R/tm_g_ae_sub.R
Original file line number Diff line number Diff line change
Expand Up @@ -184,9 +184,33 @@ srv_g_ae_sub <- function(id,
checkmate::assert_class(data, "tdata")

moduleServer(id, function(input, output, session) {
iv <- shinyvalidate::InputValidator$new()
iv$add_rule("arm_var", shinyvalidate::sv_required())
iv$enable()
iv <- reactive({
ANL <- data[[dataname]]() # nolint
ADSL <- data[["ADSL"]]() # nolint

iv <- shinyvalidate::InputValidator$new()
iv$add_rule("arm_var", shinyvalidate::sv_required(
message = "Arm Variable is required"
))
iv$add_rule("arm_var", ~ if (!is.factor(ANL[[.]])) {
"Arm Var must be a factor variable, contact developer"
})
rule_diff <- function(value, other) {
if (isTRUE(value == other)) "Control and Treatment must be different"
}
iv$add_rule("arm_trt", rule_diff, other = input$arm_ref)
iv$add_rule("arm_ref", rule_diff, other = input$arm_trt)
iv$add_rule("groups", shinyvalidate::sv_in_set(
names(ANL),
message_fmt = sprintf("Groups must be a variable in %s", dataname)
))
iv$add_rule("groups", shinyvalidate::sv_in_set(
names(ADSL),
message_fmt = "Groups must be a variable in ADSL"
))
iv$enable()
iv
})

decorate_output <- srv_g_decorate(
id = NULL,
Expand Down Expand Up @@ -289,40 +313,15 @@ srv_g_ae_sub <- function(id,
output_q <- reactive({
ANL <- data[[dataname]]() # nolint
ADSL <- data[["ADSL"]]() # nolint
validate_has_data(ANL, min_nrow = 10)
iv_comp <- shinyvalidate::InputValidator$new()
iv_comp$add_rule("arm_trt", shinyvalidate::sv_not_equal(
input$arm_ref,
message_fmt = "Must not be equal to Control"
))
iv_comp$add_rule("arm_ref", shinyvalidate::sv_not_equal(
input$arm_trt,
message_fmt = "Must not be equal to Treatment"
))
iv_comp$enable()
validate(need(iv_comp$is_valid(), "Misspecification error: please observe red flags in the encodings."))

validate(need(iv$is_valid(), "Misspecification error: please observe red flags in the encodings."))
teal::validate_has_data(ANL, min_nrow = 10, msg = sprintf("%s has not enough data", dataname))

teal::validate_inputs(iv())

validate(need(
is.factor(ANL[[input$arm_var]]),
"Selected arm variable needs to be a factor. Contact the app developer."
input$arm_trt %in% ANL[[input$arm_var]] && input$arm_ref %in% ANL[[input$arm_var]],
"Treatment or Control not found in Arm Variable. Perhaps they have been filtered out?"
))
validate(
need(
all(c(input$arm_trt, input$arm_ref) %in% levels(ADSL[[input$arm_var]])),
"Updating treatment and control selections."
)
)
validate(
need(
all(c(input$arm_trt, input$arm_ref) %in% levels(ANL[[input$arm_var]])),
"The dataset does not contain subjects with AE events from both the control and treatment arms."
),
need(
all(input$groups %in% names(ANL)) & all(input$groups %in% names(ADSL)),
"Check all selected subgroups are columns in ADAE and ADSL."
)
)

group_labels <- lapply(seq_along(input$groups), function(x) {
items <- input[[sprintf("groups__%s", x)]]
Expand Down
82 changes: 44 additions & 38 deletions R/tm_g_butterfly.R
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,11 @@
#' dataname = "ADAE",
#' right_var = choices_selected(
#' selected = "SEX",
#' choices = c("DOSE", "SEX", "ARM", "RACE", "flag1", "flag2", "flag3")
#' choices = c("SEX", "ARM", "RACE")
#' ),
#' left_var = choices_selected(
#' selected = "RACE",
#' choices = c("DOSE", "SEX", "ARM", "RACE", "flag1", "flag2", "flag3")
#' choices = c("SEX", "ARM", "RACE")
#' ),
#' category_var = choices_selected(selected = "AEBODSYS", choices = c("AEDECOD", "AEBODSYS")),
#' color_by_var = choices_selected(selected = "AETOXGR", choices = c("AETOXGR", "None")),
Expand Down Expand Up @@ -269,11 +269,35 @@ srv_g_butterfly <- function(id, data, filter_panel_api, reporter, dataname, labe
checkmate::assert_class(data, "tdata")

moduleServer(id, function(input, output, session) {
iv <- shinyvalidate::InputValidator$new()
iv$add_rule("category_var", shinyvalidate::sv_required())
iv$add_rule("right_var", shinyvalidate::sv_required())
iv$add_rule("left_var", shinyvalidate::sv_required())
iv$enable()
iv <- reactive({
ADSL <- data[["ADSL"]]() # nolint
ANL <- data[[dataname]]() # nolint

iv <- shinyvalidate::InputValidator$new()
iv$add_rule("category_var", shinyvalidate::sv_required(
message = "Category Variable is required"
))
iv$add_rule("right_var", shinyvalidate::sv_required(
message = "Right Dichotomization Variable is required"
))
iv$add_rule("left_var", shinyvalidate::sv_required(
message = "Left Dichotomization Variable is required"
))
iv$add_rule("right_var", ~ if (!is.factor(ANL[[.]])) {
"Right Dichotomization Variable must be a factor variable, contact developer"
})
iv$add_rule("left_var", ~ if (!is.factor(ANL[[.]])) {
"Left Dichotomization Variable must be a factor variable, contact developer"
})
iv$add_rule("right_val", shinyvalidate::sv_required(
message = "At least one value of Right Dichotomization Variable must be selected"
))
iv$add_rule("left_val", shinyvalidate::sv_required(
message = "At least one value of Left Dichotomization Variable must be selected"
))
iv$enable()
iv
})

options <- reactiveValues(r = NULL, l = NULL)
vars <- reactiveValues(r = NULL, l = NULL)
Expand Down Expand Up @@ -360,6 +384,19 @@ srv_g_butterfly <- function(id, data, filter_panel_api, reporter, dataname, labe
ADSL <- data[["ADSL"]]() # nolint
ANL <- data[[dataname]]() # nolint

teal::validate_has_data(ADSL, min_nrow = 0, msg = sprintf("%s Data is empty", "ADSL"))
teal::validate_has_data(ANL, min_nrow = 0, msg = sprintf("%s Data is empty", dataname))
chlebowa marked this conversation as resolved.
Show resolved Hide resolved

teal::validate_inputs(iv())

validate(
need(
all(input$right_val %in% ADSL[[input$right_var]]) &&
all(input$left_val %in% ADSL[[input$left_var]]),
"No observations for selected dichotomization values (filtered out?)"
)
)

right_var <- isolate(input$right_var)
left_var <- isolate(input$left_var)
right_val <- input$right_val
Expand All @@ -372,37 +409,6 @@ srv_g_butterfly <- function(id, data, filter_panel_api, reporter, dataname, labe
sort_by_var <- input$sort_by_var
filter_var <- input$filter_var

iv_len <- shinyvalidate::InputValidator$new()
iv_len$add_rule("right_val", shinyvalidate::sv_required("Please select at least one"))
iv_len$add_rule("left_val", shinyvalidate::sv_required("Please select at least one"))
iv_len$enable()
validate(need(iv_len$is_valid(), "Misspecification error: please observe red flags in the encodings."))

validate(
need(category_var, "Please select a category variable."),
need(nrow(ADSL) > 0, "ADSL Data has no rows"),
need(nrow(ANL) > 0, "ADAE Data has no rows"),
need(right_var, "'Right Dichotomization Variable' not selected"),
need(left_var, "'Left Dichotomization Variable' not selected")
)

validate(
need(length(right_val) > 0, "No values of 'Right Dichotomization Variable' are checked"),
need(length(left_val) > 0, "No values of 'Left Dichotomization Variable' are checked"),
need(
is.factor(ANL[[right_var]]),
"Selected 'Right Dichotomization Variable' variable needs to be a factor. Contact an app developer."
),
need(
is.factor(ANL[[left_var]]),
"Selected 'Right Dichotomization Variable' variable needs to be a factor. Contact an app developer."
),
need(
any(c(ADSL[[right_var]] %in% right_val, ADSL[[left_var]] %in% left_val)),
"ADSL Data contains no rows with either of the selected left or right dichotomization values (filtered out?)"
)
)

# if variable is not in ADSL, then take from domain VADs
varlist <- c(category_var, color_by_var, facet_var, filter_var, right_var, left_var)
varlist_from_adsl <- intersect(varlist, names(ADSL))
Expand Down
Loading