Skip to content

Commit 4e3f7fc

Browse files
committed
Merge pre-release
1 parent edc1d27 commit 4e3f7fc

File tree

3 files changed

+107
-36
lines changed

3 files changed

+107
-36
lines changed

R/tm_a_pca.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ tm_a_pca <- function(label = "Principal Component Analysis",
111111
post_output = NULL) {
112112
logger::log_info("Initializing tm_a_pca")
113113

114-
# Normalizing data types
114+
# Normalize the parameters
115115
if (inherits(dat, "data_extract_spec")) dat <- list(dat)
116116
if (inherits(ggplot2_args, "ggplot2_args")) ggplot2_args <- list(default = ggplot2_args)
117117

R/tm_a_regression.R

Lines changed: 84 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#' Scatterplot and regression model
1+
#' `teal` module: Scatterplot and regression analysis
22
#'
33
#' Module for visualizing regression analysis, including scatterplots and
44
#' various regression diagnostics plots.
@@ -14,14 +14,6 @@
1414
#' Regressor variables from an incoming dataset with filtering and selecting.
1515
#' @param response (`data_extract_spec` or `list` of multiple `data_extract_spec`)
1616
#' Response variables from an incoming dataset with filtering and selecting.
17-
#' @param alpha (`integer(1)` or `integer(3)`, optional) Specifies point opacity.
18-
#' - When the length of `alpha` is one: the plot points will have a fixed opacity.
19-
#' - When the length of `alpha` is three: the plot points opacity are dynamically adjusted based on
20-
#' vector of `value`, `min`, and `max`.
21-
#' @param size (`integer(1)` or `integer(3)`, optional) Specifies point size.
22-
#' - When the length of `size` is one: the plot point sizes will have a fixed size.
23-
#' - When the length of `size` is three: the plot points size are dynamically adjusted based on
24-
#' vector of `value`, `min`, and `max`.
2517
#' @param default_outlier_label (`character`, optional) The default column selected to label outliers.
2618
#' @param default_plot_type (`numeric`, optional) Defaults to Response vs Regressor.
2719
#' 1. Response vs Regressor
@@ -31,10 +23,25 @@
3123
#' 5. Cook's distance
3224
#' 6. Residuals vs Leverage
3325
#' 7. Cook's dist vs Leverage
26+
#' @param label_segment_threshold (`numeric(1)` or `numeric(3)`)
27+
#' Minimum distance between label and point on the plot that triggers the creation of
28+
#' a line segment between the two.
29+
#' This may happen when the label cannot be placed next to the point as it overlaps another
30+
#' label or point.
31+
#' The value is used as the `min.segment.length` parameter to the [ggrepel::geom_text_repel()] function.
32+
#'
33+
#' It can take the following forms:
34+
#' - `numeric(1)`: Fixed value used for the minimum distance and the slider is not presented in the UI.
35+
#' - `numeric(3)`: A slider is presented in the UI (under "Plot settings") to adjust the minimum distance dynamically.
36+
#'
37+
#' It takes the form of `c(value, min, max)` and it is passed to the `value_min_max`
38+
#' argument in `teal.widgets::optionalSliderInputValMinMax`.
3439
#'
3540
#' @templateVar ggnames `r regression_names`
3641
#' @template ggplot2_args_multi
3742
#'
43+
#' @inherit shared_params return
44+
#'
3845
#' @examples
3946
#' # general data example
4047
#' library(teal.widgets)
@@ -141,26 +148,32 @@ tm_a_regression <- function(label = "Regression Analysis",
141148
pre_output = NULL,
142149
post_output = NULL,
143150
default_plot_type = 1,
144-
default_outlier_label = "USUBJID") {
151+
default_outlier_label = "USUBJID",
152+
label_segment_threshold = c(0.5, 0, 10)) {
145153
logger::log_info("Initializing tm_a_regression")
146154

147-
# Normalizing data types
155+
# Normalize the parameters
148156
if (inherits(regressor, "data_extract_spec")) regressor <- list(regressor)
149157
if (inherits(response, "data_extract_spec")) response <- list(response)
150158
if (inherits(ggplot2_args, "ggplot2_args")) ggplot2_args <- list(default = ggplot2_args)
151159

152160
# Start of assertions
153161
checkmate::assert_string(label)
154162
checkmate::assert_list(regressor, types = "data_extract_spec")
163+
155164
checkmate::assert_list(response, types = "data_extract_spec")
156165
assert_single_selection(response)
157166

158167
checkmate::assert_numeric(plot_height, len = 3, any.missing = FALSE, finite = TRUE)
159168
checkmate::assert_numeric(plot_height[1], lower = plot_height[2], upper = plot_height[3], .var.name = "plot_height")
169+
160170
checkmate::assert_numeric(plot_width, len = 3, any.missing = FALSE, null.ok = TRUE, finite = TRUE)
161171
checkmate::assert_numeric(
162172
plot_width[1],
163-
lower = plot_width[2], upper = plot_width[3], null.ok = TRUE, .var.name = "plot_width"
173+
lower = plot_width[2],
174+
upper = plot_width[3],
175+
null.ok = TRUE,
176+
.var.name = "plot_width"
164177
)
165178

166179
if (length(alpha) == 1) {
@@ -188,8 +201,20 @@ tm_a_regression <- function(label = "Regression Analysis",
188201

189202
checkmate::assert_multi_class(pre_output, c("shiny.tag", "shiny.tag.list", "html"), null.ok = TRUE)
190203
checkmate::assert_multi_class(post_output, c("shiny.tag", "shiny.tag.list", "html"), null.ok = TRUE)
191-
checkmate::assert_choice(default_plot_type, seq.int(1, length(plot_choices)))
204+
checkmate::assert_choice(default_plot_type, seq.int(1L, length(plot_choices)))
192205
checkmate::assert_string(default_outlier_label)
206+
207+
if (length(label_segment_threshold) == 1) {
208+
checkmate::assert_numeric(label_segment_threshold, any.missing = FALSE, finite = TRUE)
209+
} else {
210+
checkmate::assert_numeric(label_segment_threshold, len = 3, any.missing = FALSE, finite = TRUE)
211+
checkmate::assert_numeric(
212+
label_segment_threshold[1],
213+
lower = label_segment_threshold[2],
214+
upper = label_segment_threshold[3],
215+
.var.name = "label_segment_threshold"
216+
)
217+
}
193218
# End of assertions
194219

195220
# Make UI args
@@ -287,6 +312,29 @@ ui_a_regression <- function(id, ...) {
287312
title = "Plot settings",
288313
teal.widgets::optionalSliderInputValMinMax(ns("alpha"), "Opacity:", args$alpha, ticks = FALSE),
289314
teal.widgets::optionalSliderInputValMinMax(ns("size"), "Points size:", args$size, ticks = FALSE),
315+
teal.widgets::optionalSliderInputValMinMax(
316+
inputId = ns("label_min_segment"),
317+
label = div(
318+
class = "teal-tooltip",
319+
tagList(
320+
"Label min. segment:",
321+
icon("circle-info"),
322+
span(
323+
class = "tooltiptext",
324+
paste(
325+
"Use the slider to choose the cut-off value to define minimum distance between label and point",
326+
"that generates a line segment.",
327+
"It's only valid when 'Display outlier labels' is checked."
328+
)
329+
)
330+
)
331+
),
332+
value_min_max = args$label_segment_threshold,
333+
# Extra parameters to sliderInput
334+
ticks = FALSE,
335+
step = .1,
336+
round = FALSE
337+
),
290338
selectInput(
291339
inputId = ns("ggtheme"),
292340
label = "Theme (by ggplot):",
@@ -467,10 +515,23 @@ srv_a_regression <- function(id,
467515
)
468516
})
469517

518+
label_min_segment <- reactive({
519+
input$label_min_segment
520+
})
521+
470522
outlier_label <- reactive({
471523
substitute(
472-
expr = geom_text(label = label_col, hjust = 0, vjust = 1, color = "red"),
473-
env = list(label_col = label_col())
524+
expr = ggrepel::geom_text_repel(
525+
label = label_col,
526+
color = "red",
527+
hjust = 0,
528+
vjust = 1,
529+
max.overlaps = Inf,
530+
min.segment.length = label_min_segment,
531+
segment.alpha = 0.5,
532+
seed = 123
533+
),
534+
env = list(label_col = label_col(), label_min_segment = label_min_segment())
474535
)
475536
})
476537

@@ -638,16 +699,20 @@ srv_a_regression <- function(id,
638699
plot <- substitute(
639700
expr = plot +
640701
stat_qq(
641-
geom = "text",
702+
geom = ggrepel::GeomTextRepel,
642703
label = label_col %>%
643704
data.frame(label = .) %>%
644705
dplyr::filter(label != "cooksd == NaN") %>%
645706
unlist(),
707+
color = "red",
646708
hjust = 0,
647-
vjust = 1,
648-
color = "red"
709+
vjust = 0,
710+
max.overlaps = Inf,
711+
min.segment.length = label_min_segment,
712+
segment.alpha = .5,
713+
seed = 123
649714
),
650-
env = list(plot = plot, label_col = label_col())
715+
env = list(plot = plot, label_col = label_col(), label_min_segment = label_min_segment())
651716
)
652717
}
653718

man/tm_a_regression.Rd

Lines changed: 22 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)