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

add shinyvalidate to tmg #498

Merged
merged 75 commits into from
Jan 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
1fddb7b
first batch of modules
mhallal1 Dec 22, 2022
78d57eb
Merge 1fddb7bd4e58fcae9cfc17f854d6e460c9830bcd into a9a1b87311725e57f…
mhallal1 Dec 22, 2022
a7699fb
[skip actions] Restyle files
github-actions[bot] Dec 22, 2022
e320e08
mb outliers
BLAZEWIM Dec 22, 2022
ef5693c
[skip actions] Roxygen Man Pages Auto Update
dependabot-preview[bot] Dec 22, 2022
5646d1c
clean missing data
mhallal1 Dec 23, 2022
dc26b82
outliers fixes
mhallal1 Dec 23, 2022
7fd3aae
outliers fixes2
mhallal1 Dec 23, 2022
26876f3
crosstable
mhallal1 Dec 23, 2022
4c6bb13
lintr
mhallal1 Dec 23, 2022
d231b17
NEWS + Description
mhallal1 Dec 23, 2022
5b6ea87
review Nik
mhallal1 Dec 23, 2022
eb67682
Merge branch 'main' into 420_shinyvalidate@main
mhallal1 Dec 29, 2022
aac3984
modules by AC (#499)
chlebowa Dec 29, 2022
a0ab9fd
Apply suggestions from code review
mhallal1 Dec 30, 2022
a5cf40d
Apply suggestions from code review
mhallal1 Dec 30, 2022
66f38df
tm_data_table
mhallal1 Dec 30, 2022
3e4a37b
bivariate
mhallal1 Dec 30, 2022
b200727
tm_g_association
mhallal1 Dec 30, 2022
adfb1ac
Update R/tm_missing_data.R
mhallal1 Dec 30, 2022
0ade6b3
Merge branch 'main' into 420_shinyvalidate@main
mhallal1 Dec 30, 2022
974d4b4
minor style fix
Jan 2, 2023
d545a07
remove theme validation
Jan 2, 2023
20b28b6
remove crule to rely on teal
Jan 2, 2023
761a080
add namespace prefix tor crule and restyle
Jan 2, 2023
87fdf9c
fix pkgdown
Jan 2, 2023
9abbe9c
review
mhallal1 Jan 2, 2023
b150529
merge main
mhallal1 Jan 2, 2023
efc5ebf
roll back crule
Jan 2, 2023
954c1b1
roll back crule
Jan 2, 2023
ed55a7d
Merge branch '420_shinyvalidate@main' of github.com:insightsengineeri…
Jan 2, 2023
24e3da4
improve validation in scatterplot
Jan 2, 2023
5bbf12d
additional validation in tm_g_scatterplot
Jan 2, 2023
a2686e6
enhance example in tm_g_bivariate
Jan 2, 2023
9cd1d9e
[skip actions] Roxygen Man Pages Auto Update
dependabot-preview[bot] Jan 2, 2023
32eaca7
change validation messages in tm_t_crosstable
Jan 2, 2023
4b2381d
roll back crule in tm_outliers
Jan 2, 2023
a205240
update output in tm_outliers
Jan 2, 2023
a18d363
update tm_g_scatterplot
Jan 3, 2023
b186f49
roll back crule in tm_g_response
Jan 3, 2023
796cd4f
improve rule in tm_g_outliers
Jan 3, 2023
d8285d2
tm_g_response
Jan 3, 2023
c5c0231
apply review to tm_a_pca
Jan 3, 2023
226f222
fix facetting bug
Jan 3, 2023
4753cb3
improve validation in tm_g_scatterplot
Jan 3, 2023
fc9818a
argument checks in tm_g_bivariate and tm_g_scatterplot
Jan 3, 2023
7e87056
message
Jan 4, 2023
4e385d4
fix rule in tm_t_crosstable
Jan 4, 2023
4cfe816
fix validation in tm_g_distribution
Jan 4, 2023
8ac883b
Update R/tm_g_scatterplot.R
Jan 4, 2023
28c2f1d
Apply suggestions from code review
Jan 4, 2023
2735fa9
fix vingette
Jan 4, 2023
1399311
update argument checks in tm_outliers
Jan 4, 2023
0c91c93
update error message in tm_outliers
Jan 4, 2023
98f0fdf
improve error message in tm_outliers
Jan 4, 2023
8268b9c
Fix strata_var vs test (#506)
gogonzo Jan 5, 2023
03bdf10
fix validtion in tm_g_distribution
Jan 5, 2023
9bc1959
improve reactivity in tm_outlier
Jan 5, 2023
fbefb01
bug fix
Jan 5, 2023
010aeda
improve message in tm_outliers
Jan 5, 2023
69ef244
Remove some deprecated ggplot2 functions (#507)
Jan 6, 2023
0707b91
Apply suggestions from code review
Jan 6, 2023
3e429fb
fix response
Jan 6, 2023
5ff28f3
* fix a message "summary_table not found"
gogonzo Jan 6, 2023
078c687
response
Jan 6, 2023
e035d59
Merge branch '420_shinyvalidate@main' of github.com:insightsengineeri…
gogonzo Jan 6, 2023
5afd497
scatterplot fix
Jan 6, 2023
22dce7e
Merge branch '420_shinyvalidate@main' of https://github.com/insightse…
Jan 6, 2023
292d2cb
outliers
Jan 6, 2023
dd4a596
bivariate fix
Jan 6, 2023
475f24e
Apply suggestions from code review
Jan 6, 2023
18cbb43
pca improve validation message
Jan 6, 2023
47a5724
fix distribution
Jan 6, 2023
9a423bf
Remove extract input from dist (#509)
Jan 6, 2023
e39ec80
Fix des outliers@420 shinyvalidate@main (#511)
gogonzo Jan 10, 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
1 change: 1 addition & 0 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Imports:
magrittr,
scales,
shinyjs,
shinyvalidate,
shinyWidgets,
stats,
stringr,
Expand Down
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
* Improved UI labels and plot panel title in `tm_g_association`.
* Added inputs `tm_variable_browser` module for text size and plot theme.
* Forced ggplot theme to be always selected in all modules.
* Updated encodings input checks to use `shinyvalidate::InputValidator` instead of `shiny::validate` for better UI experience.

### Bug fixes
* Fixed a bug in `tm_g_scatterplot` when selected x and y facets were the same.
Expand All @@ -20,6 +21,7 @@
### Miscellaneous

* Examples now use `scda.2022` rather than `scda.2021`.
* Replaced deprecated `ggplot2` functions `..count..`, `..density..` and `..prop..`.

# teal.modules.general 0.2.15

Expand Down
197 changes: 121 additions & 76 deletions R/tm_a_pca.R
Original file line number Diff line number Diff line change
Expand Up @@ -150,14 +150,7 @@ ui_a_pca <- function(id, ...) {
include_css_files("custom"),
teal.widgets::standard_layout(
output = teal.widgets::white_small_well(
tags$div(
class = "overflow-scroll",
uiOutput(ns("tbl_importance_ui")),
hr(),
uiOutput(ns("tbl_eigenvector_ui")),
hr(),
teal.widgets::plot_with_settings_ui(id = ns("pca_plot"))
)
uiOutput(ns("all_plots"))
),
encoding = div(
### Reporter
Expand Down Expand Up @@ -269,10 +262,63 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl
)
}

anl_merged_input <- teal.transform::merge_expression_module(
selector_list <- teal.transform::data_extract_multiple_srv(
data_extract = list(dat = dat, response = response),
datasets = data,
select_validation_rule = list(
dat = ~ if (length(.) < 2L) "Please select more than 1 variable to perform PCA.",
response = shinyvalidate::compose_rules(
shinyvalidate::sv_optional(),
~ if (isTRUE(is.element(., selector_list()$dat()$select)))
"Response must not have been used for PCA."
)
)
)

iv_r <- reactive({
iv <- shinyvalidate::InputValidator$new()
teal.transform::compose_and_enable_validators(iv, selector_list)
})

iv_extra <- shinyvalidate::InputValidator$new()
iv_extra$add_rule("x_axis", function(value) {
if (isTRUE(input$plot_type %in% c("Circle plot", "Biplot"))) {
if (!shinyvalidate::input_provided(value))
"Need X axis"
}
})
iv_extra$add_rule("y_axis", function(value) {
if (isTRUE(input$plot_type %in% c("Circle plot", "Biplot"))) {
if (!shinyvalidate::input_provided(value))
"Need Y axis"
}
})
rule_dupl <- function(...) {
if (isTRUE(input$plot_type %in% c("Circle plot", "Biplot"))) {
if (isTRUE(input$x_axis == input$y_axis))
"Please choose different X and Y axes."
}
}
iv_extra$add_rule("x_axis", rule_dupl)
iv_extra$add_rule("y_axis", rule_dupl)
iv_extra$add_rule("variables", function(value) {
if (identical(input$plot_type, "Circle plot")) {
if (!shinyvalidate::input_provided(value))
"Need Original Coordinates"
}
})
iv_extra$add_rule("pc", function(value) {
if (identical(input$plot_type, "Eigenvector plot")) {
if (!shinyvalidate::input_provided(value))
"Need PC"
}
})
iv_extra$enable()

anl_merged_input <- teal.transform::merge_expression_srv(
selector_list = selector_list,
datasets = data,
join_keys = get_join_keys(data),
data_extract = list(dat = dat, response = response)
join_keys = get_join_keys(data)
)

anl_merged_q <- reactive({
Expand All @@ -286,8 +332,7 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl
anl_q_r = anl_merged_q
)

# computation ----
computation <- reactive({
validation <- reactive({
req(merged$anl_q_r())
# inputs
keep_cols <- as.character(merged$anl_input_r()$columns_source$dat)
Expand All @@ -297,21 +342,36 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl
scale <- standardization == "center_scale"
ANL <- merged$anl_q_r()[["ANL"]] # nolint

# inputs validation
validate(need(length(keep_cols) > 1, "Please select more than 1 variable to perform PCA."))
teal::validate_has_elements(keep_cols, "Please select columns")
validate(need(
all(vapply(ANL[keep_cols], function(x) is.numeric(x) && all(!is.infinite(x)), logical(1))),
"PCA is only defined for (finite) numeric columns."
))
teal::validate_has_data(ANL, 10)
validate(need(
na_action != "none" | !anyNA(ANL[keep_cols]),
paste(
"There are NAs in the dataset. Please deal with them in preprocessing",
'or select "Drop" in the NA actions inside the encodings panel (left).'
"or select \"Drop\" in the NA actions inside the encodings panel (left)."
)
))
if (scale) {
not_single <- vapply(ANL[keep_cols], function(column) length(unique(column)) != 1, FUN.VALUE = logical(1))

msg <- paste0(
"You have selected `Center & Scale` under `Standardization` in the `Pre-processing` panel, ",
"but one or more of your columns has/have a variance value of zero, indicating all values are identical"
)
validate(need(all(not_single), msg))
}
})

# computation ----
computation <- reactive({
validation()

# inputs
keep_cols <- as.character(merged$anl_input_r()$columns_source$dat)
na_action <- input$na_action
standardization <- input$standardization
center <- standardization %in% c("center", "center_scale") # nolint
scale <- standardization == "center_scale"
ANL <- merged$anl_q_r()[["ANL"]] # nolint

qenv <- teal.code::eval_code(
merged$anl_q_r(),
Expand All @@ -328,16 +388,6 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl
)
}

if (scale) {
not_single <- vapply(ANL[keep_cols], function(column) length(unique(column)) != 1, FUN.VALUE = logical(1))

msg <- paste0(
"You have selected `Center & Scale` under `Standardization` in the `Pre-processing` panel, ",
"but one or more of your columns has/have a variance value of zero, indicating all values are identical"
)
validate(need(all(not_single), msg))
}

qenv <- teal.code::eval_code(
qenv,
substitute(
Expand Down Expand Up @@ -366,6 +416,7 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl
# plot args ----
output$plot_settings <- renderUI({
# reactivity triggers
req(iv_r()$is_valid())
req(computation())
qenv <- computation()

Expand Down Expand Up @@ -405,7 +456,6 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl
# plot elbow ----
plot_elbow <- function(base_q) {
ggtheme <- input$ggtheme
validate(need(ggtheme, "Please select a theme."))
rotate_xaxis_labels <- input$rotate_xaxis_labels # nolint
font_size <- input$font_size # nolint

Expand All @@ -417,7 +467,7 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl
theme = list(
legend.position = "right",
legend.spacing.y = quote(grid::unit(-5, "pt")),
legend.title = quote(element_text(vjust = 8)),
legend.title = quote(element_text(vjust = 25)),
axis.text.x = substitute(
element_text(angle = angle_value, hjust = hjust_value),
list(angle_value = angle_value, hjust_value = hjust_value)
Expand Down Expand Up @@ -481,19 +531,10 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl

# plot circle ----
plot_circle <- function(base_q) {
validate(
need(input$x_axis, "Need additional plot settings - x axis"),
need(input$y_axis, "Need additional plot settings - y axis"),
need(input$variables, "Need additional plot settings - variables")
)
validate(need(input$x_axis != input$y_axis, "Please choose different X and Y axes."))

x_axis <- input$x_axis # nolint
y_axis <- input$y_axis # nolint
variables <- input$variables # nolint

ggtheme <- input$ggtheme
validate(need(ggtheme, "Please select a theme."))

rotate_xaxis_labels <- input$rotate_xaxis_labels # nolint
font_size <- input$font_size # nolint
Expand Down Expand Up @@ -563,12 +604,6 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl

# plot biplot ----
plot_biplot <- function(base_q) {
validate(
need(input$x_axis, "Need additional plot settings - x axis"),
need(input$y_axis, "Need additional plot settings - y axis")
)
validate(need(isTRUE(input$x_axis != input$y_axis), "Please choose different X and Y axes."))

qenv <- base_q

ANL <- qenv[["ANL"]] # nolint
Expand All @@ -581,7 +616,6 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl
pca <- qenv[["pca"]]

ggtheme <- input$ggtheme
validate(need(ggtheme, "Please select a theme."))

rotate_xaxis_labels <- input$rotate_xaxis_labels # nolint
alpha <- input$alpha # nolint
Expand All @@ -602,8 +636,8 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl
qenv,
substitute(
expr = {
r <- sqrt(qchisq(0.69, df = 2)) * prod(colMeans(pca_rot ^ 2)) ^ (1 / 4) # styler: off
v_scale <- rowSums(pca$rotation ^ 2) # styler: off
r <- sqrt(qchisq(0.69, df = 2)) * prod(colMeans(pca_rot ^ 2)) ^ (1 / 4) # styler: off
v_scale <- rowSums(pca$rotation ^ 2) # styler: off

rot_vars <- pca$rotation[, c(x_axis, y_axis)] %>%
dplyr::as_tibble(rownames = "label") %>%
Expand Down Expand Up @@ -651,10 +685,6 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl
)
dev_labs <- list()
} else {
validate(need(
!resp_col %in% dat_cols,
"Response column must be different from the original variables (that were used for PCA)."
))

rp_keys <- setdiff(
colnames(ANL),
Expand All @@ -676,8 +706,8 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl
dev_labs <- list(color = varname_w_label(resp_col, ANL))

scales_biplot <- if (is.character(response) ||
is.factor(response) ||
(is.numeric(response) && length(unique(response)) <= 6)) {
is.factor(response) ||
(is.numeric(response) && length(unique(response)) <= 6)) {
qenv <- teal.code::eval_code(
qenv,
quote(pca_rot$response <- as.factor(response))
Expand Down Expand Up @@ -792,12 +822,8 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl

# plot pc_var ----
plot_pc_var <- function(base_q) {
validate(need(input$pc, "Need additional plot settings - PC"))

pc <- input$pc # nolint

ggtheme <- input$ggtheme
validate(need(ggtheme, "Please select a theme."))

rotate_xaxis_labels <- input$rotate_xaxis_labels # nolint
font_size <- input$font_size # nolint
Expand Down Expand Up @@ -831,9 +857,9 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl
quote(ggplot(pca_rot)),
substitute(
geom_bar(aes_string(x = "Variable", y = pc),
stat = "identity",
color = "black",
fill = c(getOption("ggplot2.discrete.colour"), "lightblue")[1]
stat = "identity",
color = "black",
fill = c(getOption("ggplot2.discrete.colour"), "lightblue")[1]
),
env = list(pc = pc)
),
Expand Down Expand Up @@ -876,20 +902,22 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl
# plot final ----
output_q <- reactive({
req(computation())
if (input$plot_type == "Elbow plot") {
plot_elbow(computation())
} else if (input$plot_type == "Circle plot") {
plot_circle(computation())
} else if (input$plot_type == "Biplot") {
plot_biplot(computation())
} else if (input$plot_type == "Eigenvector plot") {
plot_pc_var(computation())
} else {
stop("Unknown plot")
}
# teal::validate_inputs_segregated(list("Some inputs require attention" = iv_r(),
# "Plot settings are required" = iv_extra))
teal::validate_inputs(iv_r())
teal::validate_inputs(iv_extra, header = "Plot settings are required")

switch(input$plot_type,
"Elbow plot" = plot_elbow(computation()),
"Circle plot" = plot_circle(computation()),
"Biplot" = plot_biplot(computation()),
"Eigenvector plot" = plot_pc_var(computation()),
stop("Unknown plot"))
})

plot_r <- reactive(output_q()[["g"]])
plot_r <- reactive({
output_q()[["g"]]
})

pws <- teal.widgets::plot_with_settings_srv(
id = "pca_plot",
Expand Down Expand Up @@ -938,6 +966,23 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl
)
})

output$all_plots <- renderUI({
# teal::validate_inputs_segregated(list("Some inputs require attention" = iv_r(),
# "Plot settings are required" = iv_extra))
teal::validate_inputs(iv_r())
teal::validate_inputs(iv_extra, header = "Plot settings are required")

validation()
tags$div(
class = "overflow-scroll",
uiOutput(session$ns("tbl_importance_ui")),
hr(),
uiOutput(session$ns("tbl_eigenvector_ui")),
hr(),
teal.widgets::plot_with_settings_ui(id = session$ns("pca_plot"))
)
})

teal.widgets::verbatim_popup_srv(
id = "warning",
verbatim_content = reactive(teal.code::get_warnings(output_q())),
Expand Down
Loading