From 1ad4601fc1f5fa2fa893fa613197899f92d0d378 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 4 Jul 2025 12:32:35 +0000
Subject: [PATCH 01/16] Initial plan
From 43083dfca90eae71904da187457d967f101e2d3b Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 4 Jul 2025 12:40:43 +0000
Subject: [PATCH 02/16] Fix tm_outliers to work without join keys
Co-authored-by: m7pr <133694481+m7pr@users.noreply.github.com>
---
R/tm_outliers.R | 44 ++++++++-----
tests/testthat/test-shinytest2-tm_outliers.R | 66 ++++++++++++++++++++
2 files changed, 94 insertions(+), 16 deletions(-)
diff --git a/R/tm_outliers.R b/R/tm_outliers.R
index e15ba7635..e7af7640e 100644
--- a/R/tm_outliers.R
+++ b/R/tm_outliers.R
@@ -616,25 +616,37 @@ srv_outliers <- function(id, data, reporter, filter_panel_api, outlier_var,
)
# ANL_OUTLIER_EXTENDED is the base table
- qenv <- teal.code::eval_code(
- qenv,
- substitute(
- expr = {
- ANL_OUTLIER_EXTENDED <- dplyr::left_join(
- ANL_OUTLIER,
- dplyr::select(
- dataname,
- dplyr::setdiff(names(dataname), dplyr::setdiff(names(ANL_OUTLIER), join_keys))
- ),
- by = join_keys
+ join_keys <- as.character(teal.data::join_keys(data())[dataname_first, dataname_first])
+
+ if (length(join_keys) == 0) {
+ # No join keys defined - working with single dataset, no join needed
+ # ANL_OUTLIER already contains all necessary columns
+ qenv <- teal.code::eval_code(
+ qenv,
+ quote(ANL_OUTLIER_EXTENDED <- ANL_OUTLIER)
+ )
+ } else {
+ # Join keys exist - perform left join as before
+ qenv <- teal.code::eval_code(
+ qenv,
+ substitute(
+ expr = {
+ ANL_OUTLIER_EXTENDED <- dplyr::left_join(
+ ANL_OUTLIER,
+ dplyr::select(
+ dataname,
+ dplyr::setdiff(names(dataname), dplyr::setdiff(names(ANL_OUTLIER), join_keys))
+ ),
+ by = join_keys
+ )
+ },
+ env = list(
+ dataname = as.name(dataname_first),
+ join_keys = join_keys
)
- },
- env = list(
- dataname = as.name(dataname_first),
- join_keys = as.character(teal.data::join_keys(data())[dataname_first, dataname_first])
)
)
- )
+ }
qenv <- if (length(categorical_var) > 0) {
qenv <- teal.code::eval_code(
diff --git a/tests/testthat/test-shinytest2-tm_outliers.R b/tests/testthat/test-shinytest2-tm_outliers.R
index 9468f7653..4bb1166bd 100644
--- a/tests/testthat/test-shinytest2-tm_outliers.R
+++ b/tests/testthat/test-shinytest2-tm_outliers.R
@@ -319,3 +319,69 @@ testthat::test_that("e2e - tm_outliers: Outlier table is displayed with proper c
app_driver$stop()
})
+
+testthat::test_that("e2e - tm_outliers: works without join keys", {
+ # Test for issue where tm_outliers fails if data has no joining keys
+ # This test reproduces the exact scenario described in the issue
+ testthat::skip("chromium")
+ skip_if_too_deep(5)
+
+ # Create data without join keys (as per issue description)
+ data <- teal.data::teal_data()
+ data <- within(data, {
+ CO2 <- CO2 # nolint: object_name
+ })
+ # Note: No join_keys defined here, which should NOT cause the issue after fix
+
+ vars <- teal.transform::choices_selected(
+ teal.transform::variable_choices(
+ data[["CO2"]],
+ c("Plant", "Type", "Treatment")
+ )
+ )
+
+ # This should NOT fail after the fix
+ app_driver <- init_teal_app_driver(
+ data = data,
+ modules = tm_outliers(
+ outlier_var = list(
+ teal.transform::data_extract_spec(
+ dataname = "CO2",
+ select = teal.transform::select_spec(
+ label = "Select variable:",
+ choices = teal.transform::variable_choices(data[["CO2"]], c("conc", "uptake")),
+ selected = "uptake",
+ multiple = FALSE,
+ fixed = FALSE
+ )
+ )
+ ),
+ categorical_var = list(
+ teal.transform::data_extract_spec(
+ dataname = "CO2",
+ filter = teal.transform::filter_spec(
+ vars = vars,
+ choices = teal.transform::value_choices(data[["CO2"]], vars$selected),
+ selected = teal.transform::value_choices(data[["CO2"]], vars$selected),
+ multiple = TRUE
+ )
+ )
+ ),
+ ggplot2_args = list(
+ teal.widgets::ggplot2_args(
+ labs = list(subtitle = "Plot generated by Outliers Module")
+ )
+ )
+ )
+ )
+
+ app_driver$expect_no_shiny_error()
+
+ # Verify the module loads correctly
+ testthat::expect_equal(
+ app_driver$get_text("#teal-teal_modules-active_tab .active"),
+ "Outliers Module"
+ )
+
+ app_driver$stop()
+})
From d9f67240445f5aeb9ba40671b11186a4b2ae1e45 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 4 Jul 2025 12:44:07 +0000
Subject: [PATCH 03/16] Add documentation example for tm_outliers without join
keys
Co-authored-by: m7pr <133694481+m7pr@users.noreply.github.com>
---
R/tm_outliers.R | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 48 insertions(+)
diff --git a/R/tm_outliers.R b/R/tm_outliers.R
index e7af7640e..2fd22d15a 100644
--- a/R/tm_outliers.R
+++ b/R/tm_outliers.R
@@ -51,6 +51,54 @@
#' {{ next_example }}
#' @examples
#'
+#' # simple data example without join keys
+#' data <- teal_data()
+#' data <- within(data, {
+#' CO2 <- CO2
+#' })
+#'
+#' vars <- choices_selected(variable_choices(data[["CO2"]], c("Plant", "Type", "Treatment")))
+#'
+#' app <- init(
+#' data = data,
+#' modules = modules(
+#' tm_outliers(
+#' outlier_var = list(
+#' data_extract_spec(
+#' dataname = "CO2",
+#' select = select_spec(
+#' label = "Select variable:",
+#' choices = variable_choices(data[["CO2"]], c("conc", "uptake")),
+#' selected = "uptake",
+#' multiple = FALSE,
+#' fixed = FALSE
+#' )
+#' )
+#' ),
+#' categorical_var = list(
+#' data_extract_spec(
+#' dataname = "CO2",
+#' filter = filter_spec(
+#' vars = vars,
+#' choices = value_choices(data[["CO2"]], vars$selected),
+#' selected = value_choices(data[["CO2"]], vars$selected),
+#' multiple = TRUE
+#' )
+#' )
+#' )
+#' )
+#' )
+#' )
+#' if (interactive()) {
+#' shinyApp(app$ui, app$server)
+#' }
+#'
+#' @examplesShinylive
+#' library(teal.modules.general)
+#' interactive <- function() TRUE
+#' {{ next_example }}
+#' @examples
+#'
#' # general data example
#' data <- teal_data()
#' data <- within(data, {
From 4de5d68852bfd1198c6e012462084882c5f3d048 Mon Sep 17 00:00:00 2001
From: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
Date: Fri, 4 Jul 2025 12:51:53 +0000
Subject: [PATCH 04/16] [skip style] [skip vbump] Restyle files
---
R/tm_outliers.R | 2 +-
tests/testthat/test-shinytest2-tm_outliers.R | 14 +++++++-------
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/R/tm_outliers.R b/R/tm_outliers.R
index 2fd22d15a..eb03dc7e5 100644
--- a/R/tm_outliers.R
+++ b/R/tm_outliers.R
@@ -665,7 +665,7 @@ srv_outliers <- function(id, data, reporter, filter_panel_api, outlier_var,
# ANL_OUTLIER_EXTENDED is the base table
join_keys <- as.character(teal.data::join_keys(data())[dataname_first, dataname_first])
-
+
if (length(join_keys) == 0) {
# No join keys defined - working with single dataset, no join needed
# ANL_OUTLIER already contains all necessary columns
diff --git a/tests/testthat/test-shinytest2-tm_outliers.R b/tests/testthat/test-shinytest2-tm_outliers.R
index 4bb1166bd..5cdc8923a 100644
--- a/tests/testthat/test-shinytest2-tm_outliers.R
+++ b/tests/testthat/test-shinytest2-tm_outliers.R
@@ -325,21 +325,21 @@ testthat::test_that("e2e - tm_outliers: works without join keys", {
# This test reproduces the exact scenario described in the issue
testthat::skip("chromium")
skip_if_too_deep(5)
-
+
# Create data without join keys (as per issue description)
data <- teal.data::teal_data()
data <- within(data, {
CO2 <- CO2 # nolint: object_name
})
# Note: No join_keys defined here, which should NOT cause the issue after fix
-
+
vars <- teal.transform::choices_selected(
teal.transform::variable_choices(
- data[["CO2"]],
+ data[["CO2"]],
c("Plant", "Type", "Treatment")
)
)
-
+
# This should NOT fail after the fix
app_driver <- init_teal_app_driver(
data = data,
@@ -374,14 +374,14 @@ testthat::test_that("e2e - tm_outliers: works without join keys", {
)
)
)
-
+
app_driver$expect_no_shiny_error()
-
+
# Verify the module loads correctly
testthat::expect_equal(
app_driver$get_text("#teal-teal_modules-active_tab .active"),
"Outliers Module"
)
-
+
app_driver$stop()
})
From 8063a70e8b7e1ebacc109994938fe73f5c178981 Mon Sep 17 00:00:00 2001
From: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
Date: Fri, 4 Jul 2025 12:57:56 +0000
Subject: [PATCH 05/16] [skip roxygen] [skip vbump] Roxygen Man Pages Auto
Update
---
man/tm_outliers.Rd | 50 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 49 insertions(+), 1 deletion(-)
diff --git a/man/tm_outliers.Rd b/man/tm_outliers.Rd
index f8c15278d..1e3683fcb 100644
--- a/man/tm_outliers.Rd
+++ b/man/tm_outliers.Rd
@@ -102,6 +102,49 @@ To learn more please refer to the vignette
\examples{
+# simple data example without join keys
+data <- teal_data()
+data <- within(data, {
+ CO2 <- CO2
+})
+
+vars <- choices_selected(variable_choices(data[["CO2"]], c("Plant", "Type", "Treatment")))
+
+app <- init(
+ data = data,
+ modules = modules(
+ tm_outliers(
+ outlier_var = list(
+ data_extract_spec(
+ dataname = "CO2",
+ select = select_spec(
+ label = "Select variable:",
+ choices = variable_choices(data[["CO2"]], c("conc", "uptake")),
+ selected = "uptake",
+ multiple = FALSE,
+ fixed = FALSE
+ )
+ )
+ ),
+ categorical_var = list(
+ data_extract_spec(
+ dataname = "CO2",
+ filter = filter_spec(
+ vars = vars,
+ choices = value_choices(data[["CO2"]], vars$selected),
+ selected = value_choices(data[["CO2"]], vars$selected),
+ multiple = TRUE
+ )
+ )
+ )
+ )
+ )
+)
+if (interactive()) {
+ shinyApp(app$ui, app$server)
+}
+
+
# general data example
data <- teal_data()
data <- within(data, {
@@ -197,11 +240,16 @@ if (interactive()) {
\section{Examples in Shinylive}{
\describe{
\item{example-1}{
+ \href{https://shinylive.io/r/app/#code=NobwRAdghgtgpmAXGKAHVA6ASmANGAYwHsIAXOMpMAGwEsAjAJykYE8AKcqajGIgEwCu1OAGcMAcwpxm1AJQAdCLTIyoBUrQBucAAQAeALS6AZoIgbaJdnN0AVLAFUAokrcQAxLtG0YqEbr8UKRQunAAHrD+egDutKQAFkSCpLoAVkQqugDWcKyiSkEhBsZc1AD6RVA2hcGhRrpxiSrsVbi6IEq6ugDCAPIATCW9g0oAvooQSlososMESbQEYuWicCIacPzsM4y0UPQi5QuZy6KtdcDACmD9AzcAug-tBOw3AArUUGQ37Td2rFQcF+un+jDgwXgPzAclh7jQqGGKnibwg3SqugAvIE6rguro+EIRHNsYThGJUd1uqQYOVkqQ6DJzviqbp6YzGOVdljdHRRKRKayqVVyhFSMwNKsga8WUL0XVoPAeTc7r9ZXK1htUtjNXBJaJpYK5ayvvR1sqwABldZ61K7faHOCINVo42sk5LMQ8+0HI4es4XEJXFWjMBPF5vQgkAggm6CVAhXI3WF411u7q6zb8C3xxPAvDq40wYSaaI8gBiAEEADKW5yp9NUky0cJbCs1uuF1mTN09oVyBtCgjBOASIh7YcVbnYvkCrs4kKi8Li9SkKV6o3GqqKvTYkP3Atp43N6jkRg8k9n9cyo9u3Yk3T3weN-1e7EzaiCODHRYBqrB25Q3DR9ZgAEkzch+AHedWQgtt324L8f1OCl-2uQCD2A+9wJtLNoNvIsS1oMtsQcFwYN0Ps5SoqkaL7SZJloExdHYFQz1XbQ4BsWxOldUQEhUVhK3QdgEVAwRaHaMS1kYHRGEmMYlDAMYHiAA}{Open in Shinylive}
+ \if{html}{\out{}}
+ \if{html}{\out{}}
+ }
+ \item{example-2}{
\href{https://shinylive.io/r/app/#code=NobwRAdghgtgpmAXGKAHVA6ASmANGAYwHsIAXOMpMAGwEsAjAJykYE8AKcqajGIgEwCu1OAGcMAcwpxm1AJQAdCLTIyoBUrQBucAAQAeALS6AZoIgbaJdnN0AVLAFUAokrcQAxLqkQ11XfxQpFC6cAAesKgiSoHBBsZc1AD6sVA2MUEhRroA7rSkABYq7Km4uiBKuroAwgDyAEzxNQ2VzfXAwApgqIy0MCysSQDWcKxdALrjTaJwAI5JIhDsEIxEOex19XKKEAC+OwBWRCrDo6IlmbbZRycjrOc3EKccXZtdZa8teLpdPX0Dzy623cWhYoiaBAKxwIYiSMxEGjg-HYoN6UHoIiSkOhYguwQ6n3qE3GZQI7C6AAVqFAyO8fmA7KxUHA6V07Iw4EF4LSwNsdko0Kgmip8uSIFVUroALwBTK4Vp8IQicEyxXCXGtKqkGBJIiCUh0GTnTVVXR6g20GRJVHS3R0USkMWm52y4JJcKkZgaOHMskml2ummwPQywnvf0u+FwDS2qPe0S+p0Bl3U+hwfyhsAAZXT0dIulRtHRIkQ4fFyed2NoMJVBZYRYxcCxUOruNSBLAbzAk1J5MIJAIrLAglQwRGQLk8vLFaqcfI-FtXRHY5ZeAjAZgwk0URDugAYgBBAAyWecU5nppMtDCSNth5PrmnyZ2FZfLsnEYIQTgEiIvS-yQ2jK9qOuugbumEnrqKQPrRkmFapNA8CLp2XznjOV7UOQjC2ph2GwX6T4VqitYkehF5VjWtqgtQghNpRbaZB2XY9nWjCiAAJHOSIfkRybcQuMo0XRzY4uc7adKhRLdiSbGcQJvEXlUm5YbQO62g4LhgVUb4Brppr6W+Ow7LQJi6OwKjYdB2hwDYtgVOWohFBArAHug7CChxgi0GUnkzIwOiMDsuxKGAuzjEAA}{Open in Shinylive}
\if{html}{\out{}}
\if{html}{\out{}}
}
- \item{example-2}{
+ \item{example-3}{
\href{https://shinylive.io/r/app/#code=NobwRAdghgtgpmAXGKAHVA6ASmANGAYwHsIAXOMpMAGwEsAjAJykYE8AKcqajGIgEwCu1OAGcMAcwpxm1AJQAdCLTIyoBUrQBucAAQAeALS6AZoIgbaJdnN0AVLAFUAokrcQAxLoDCAEQCSAMreuvxQpFC6cAAesKgiSmERBsZc1AD6SVA2ieGRRroA7rSkABYq7Fm4uiBKuroAgr6BADIpumkYWYiIjE2tSgC+ihAAVkQq6QDWcKyilXm2BfxwJlDCpOkE-LSiBOnjkzNzwNDw81lyALruaxrpWiyi6VD8otTtZ2LsAGK01ORGOxdg4XNVRGh4hwssBgAowP0WvCrldqrsMHdSERGHJcUpHoxRO0CKUJgQxOlRHARBo4Px2ATaFB6CItqTaOSLnlYfDEcjUaZ1JsCc9Xu88RB3EpIe0VCV2HVQnldABeJURXCKvhCEREtXa4TfRX1UgwdJEQSkOgyebG+q6C1W2gyB4sVW6OiiUgKiD2v3qqDpGKkZj3USoOAEH3+-1ZL7u3nNJF4O0xqk00ju9ORzbhyPRmP+6jM6kJsCBak53SM5kiRDwzW+wt+klksTumssuBsttciI8hFJ-nVKO8gDirjwunhACEALJYADSWAAjPDcY3m37s7T+GWGhOG6nCzANrR4no1T8Gi1As5N1v6iZaNE6e7r7fXE3myMf8e5A+LbhHAEjYhy3Cuow7qet6x71FkQbRCGQqUhGo7foWcawJe06DgMKYYTGz4AjI7rEYCqH5nB-oih2TyAVurYcu2aqPNQgjdkxnILP2cJ4cmKLVCKAAkO7kPwAHUdula7nR7Gcey3EwnxfJgIJ1ZPKJMniZJhEnmeF7uqCX6Pr+hZmX6Fm6GZIwjLQJi6MCqihpoOg2LYtRNqI5QQKwDToOwkLCYItDVEFVKMDoOJDEoYCDFcQA}{Open in Shinylive}
\if{html}{\out{}}
\if{html}{\out{}}
From 113d0d8c69a550a8d440a0d63417d97973ec3b83 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 4 Jul 2025 13:16:29 +0000
Subject: [PATCH 06/16] Fix merge_expression_srv to handle single datasets
without join keys
Co-authored-by: m7pr <133694481+m7pr@users.noreply.github.com>
---
R/tm_outliers.R | 65 +++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 60 insertions(+), 5 deletions(-)
diff --git a/R/tm_outliers.R b/R/tm_outliers.R
index eb03dc7e5..4f09e7651 100644
--- a/R/tm_outliers.R
+++ b/R/tm_outliers.R
@@ -486,11 +486,66 @@ srv_outliers <- function(id, data, reporter, filter_panel_api, outlier_var,
}
})
- anl_merged_input <- teal.transform::merge_expression_srv(
- selector_list = reactive_select_input,
- datasets = data,
- merge_function = "dplyr::inner_join"
- )
+ anl_merged_input <- reactive({
+ # Check if we have join keys available
+ dataname_first <- names(data())[[1]]
+ join_keys <- teal.data::join_keys(data())[dataname_first, dataname_first]
+
+ if (length(join_keys) == 0) {
+ # No join keys available - create a simple data extract without merging
+ # This handles the case where we have only one dataset without join keys
+ selectors <- reactive_select_input()
+
+ # Get the first (primary) selector for the outlier variable
+ outlier_selector <- selectors$outlier_var
+
+ if (!is.null(outlier_selector)) {
+ sel_result <- outlier_selector()
+ if (!is.null(sel_result)) {
+ # Create a simple ANL assignment without merging
+ dataname <- sel_result$dataname
+
+ # Handle categorical variable if present
+ categorical_selector <- selectors$categorical_var
+ categorical_cols <- character(0)
+ if (!is.null(categorical_selector)) {
+ cat_result <- categorical_selector()
+ if (!is.null(cat_result) && !is.null(cat_result$filter)) {
+ # Extract filter variable names
+ filter_vars <- cat_result$filter
+ if (length(filter_vars) > 0) {
+ categorical_cols <- names(filter_vars)
+ }
+ }
+ }
+
+ return(list(
+ expr = substitute(ANL <- dataname, list(dataname = as.name(dataname))),
+ columns_source = list(
+ outlier_var = sel_result$select,
+ categorical_var = categorical_cols
+ )
+ ))
+ }
+ }
+
+ # Fallback - return first dataset
+ return(list(
+ expr = substitute(ANL <- dataname, list(dataname = as.name(dataname_first))),
+ columns_source = list(
+ outlier_var = character(0),
+ categorical_var = character(0)
+ )
+ ))
+ } else {
+ # Join keys exist - use the standard merge approach
+ teal.transform::merge_expression_srv(
+ selector_list = reactive_select_input,
+ datasets = data,
+ merge_function = "dplyr::inner_join"
+ )()
+ }
+ })
anl_merged_q <- reactive({
req(anl_merged_input())
From 322a7170411c5f76ecdbeb5606ee9dd38a1d75ad Mon Sep 17 00:00:00 2001
From: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
Date: Fri, 4 Jul 2025 13:25:04 +0000
Subject: [PATCH 07/16] [skip style] [skip vbump] Restyle files
---
R/tm_outliers.R | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/R/tm_outliers.R b/R/tm_outliers.R
index 4f09e7651..e88e1d558 100644
--- a/R/tm_outliers.R
+++ b/R/tm_outliers.R
@@ -490,21 +490,21 @@ srv_outliers <- function(id, data, reporter, filter_panel_api, outlier_var,
# Check if we have join keys available
dataname_first <- names(data())[[1]]
join_keys <- teal.data::join_keys(data())[dataname_first, dataname_first]
-
+
if (length(join_keys) == 0) {
# No join keys available - create a simple data extract without merging
# This handles the case where we have only one dataset without join keys
selectors <- reactive_select_input()
-
+
# Get the first (primary) selector for the outlier variable
outlier_selector <- selectors$outlier_var
-
+
if (!is.null(outlier_selector)) {
sel_result <- outlier_selector()
if (!is.null(sel_result)) {
# Create a simple ANL assignment without merging
dataname <- sel_result$dataname
-
+
# Handle categorical variable if present
categorical_selector <- selectors$categorical_var
categorical_cols <- character(0)
@@ -518,7 +518,7 @@ srv_outliers <- function(id, data, reporter, filter_panel_api, outlier_var,
}
}
}
-
+
return(list(
expr = substitute(ANL <- dataname, list(dataname = as.name(dataname))),
columns_source = list(
@@ -528,7 +528,7 @@ srv_outliers <- function(id, data, reporter, filter_panel_api, outlier_var,
))
}
}
-
+
# Fallback - return first dataset
return(list(
expr = substitute(ANL <- dataname, list(dataname = as.name(dataname_first))),
From 0e6b8024d96762de0ceae5027c72e5324c3d8219 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 4 Jul 2025 13:39:33 +0000
Subject: [PATCH 08/16] Simplify tm_outliers fix for datasets without join keys
Co-authored-by: m7pr <133694481+m7pr@users.noreply.github.com>
---
R/tm_outliers.R | 116 +++++++-----------------------------------------
1 file changed, 15 insertions(+), 101 deletions(-)
diff --git a/R/tm_outliers.R b/R/tm_outliers.R
index e88e1d558..54fad2527 100644
--- a/R/tm_outliers.R
+++ b/R/tm_outliers.R
@@ -51,54 +51,6 @@
#' {{ next_example }}
#' @examples
#'
-#' # simple data example without join keys
-#' data <- teal_data()
-#' data <- within(data, {
-#' CO2 <- CO2
-#' })
-#'
-#' vars <- choices_selected(variable_choices(data[["CO2"]], c("Plant", "Type", "Treatment")))
-#'
-#' app <- init(
-#' data = data,
-#' modules = modules(
-#' tm_outliers(
-#' outlier_var = list(
-#' data_extract_spec(
-#' dataname = "CO2",
-#' select = select_spec(
-#' label = "Select variable:",
-#' choices = variable_choices(data[["CO2"]], c("conc", "uptake")),
-#' selected = "uptake",
-#' multiple = FALSE,
-#' fixed = FALSE
-#' )
-#' )
-#' ),
-#' categorical_var = list(
-#' data_extract_spec(
-#' dataname = "CO2",
-#' filter = filter_spec(
-#' vars = vars,
-#' choices = value_choices(data[["CO2"]], vars$selected),
-#' selected = value_choices(data[["CO2"]], vars$selected),
-#' multiple = TRUE
-#' )
-#' )
-#' )
-#' )
-#' )
-#' )
-#' if (interactive()) {
-#' shinyApp(app$ui, app$server)
-#' }
-#'
-#' @examplesShinylive
-#' library(teal.modules.general)
-#' interactive <- function() TRUE
-#' {{ next_example }}
-#' @examples
-#'
#' # general data example
#' data <- teal_data()
#' data <- within(data, {
@@ -487,58 +439,24 @@ srv_outliers <- function(id, data, reporter, filter_panel_api, outlier_var,
})
anl_merged_input <- reactive({
- # Check if we have join keys available
dataname_first <- names(data())[[1]]
join_keys <- teal.data::join_keys(data())[dataname_first, dataname_first]
-
+
if (length(join_keys) == 0) {
- # No join keys available - create a simple data extract without merging
- # This handles the case where we have only one dataset without join keys
- selectors <- reactive_select_input()
-
- # Get the first (primary) selector for the outlier variable
- outlier_selector <- selectors$outlier_var
-
- if (!is.null(outlier_selector)) {
- sel_result <- outlier_selector()
- if (!is.null(sel_result)) {
- # Create a simple ANL assignment without merging
- dataname <- sel_result$dataname
-
- # Handle categorical variable if present
- categorical_selector <- selectors$categorical_var
- categorical_cols <- character(0)
- if (!is.null(categorical_selector)) {
- cat_result <- categorical_selector()
- if (!is.null(cat_result) && !is.null(cat_result$filter)) {
- # Extract filter variable names
- filter_vars <- cat_result$filter
- if (length(filter_vars) > 0) {
- categorical_cols <- names(filter_vars)
- }
- }
- }
-
- return(list(
- expr = substitute(ANL <- dataname, list(dataname = as.name(dataname))),
- columns_source = list(
- outlier_var = sel_result$select,
- categorical_var = categorical_cols
- )
- ))
- }
- }
-
- # Fallback - return first dataset
- return(list(
+ # No join keys - create simple assignment expression
+ list(
expr = substitute(ANL <- dataname, list(dataname = as.name(dataname_first))),
columns_source = list(
- outlier_var = character(0),
- categorical_var = character(0)
+ outlier_var = reactive_select_input()$outlier_var()$select,
+ categorical_var = if (!is.null(reactive_select_input()$categorical_var)) {
+ names(reactive_select_input()$categorical_var()$filter)
+ } else {
+ character(0)
+ }
)
- ))
+ )
} else {
- # Join keys exist - use the standard merge approach
+ # Join keys exist - use standard merge
teal.transform::merge_expression_srv(
selector_list = reactive_select_input,
datasets = data,
@@ -720,16 +638,12 @@ srv_outliers <- function(id, data, reporter, filter_panel_api, outlier_var,
# ANL_OUTLIER_EXTENDED is the base table
join_keys <- as.character(teal.data::join_keys(data())[dataname_first, dataname_first])
-
+
if (length(join_keys) == 0) {
- # No join keys defined - working with single dataset, no join needed
- # ANL_OUTLIER already contains all necessary columns
- qenv <- teal.code::eval_code(
- qenv,
- quote(ANL_OUTLIER_EXTENDED <- ANL_OUTLIER)
- )
+ # No join keys - no join needed
+ qenv <- teal.code::eval_code(qenv, quote(ANL_OUTLIER_EXTENDED <- ANL_OUTLIER))
} else {
- # Join keys exist - perform left join as before
+ # Join keys exist - perform left join
qenv <- teal.code::eval_code(
qenv,
substitute(
From c0360c6477c4751e4586e4ea7ce5a2bc7c3240ca Mon Sep 17 00:00:00 2001
From: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
Date: Fri, 4 Jul 2025 14:06:15 +0000
Subject: [PATCH 09/16] [skip style] [skip vbump] Restyle files
---
R/tm_outliers.R | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/R/tm_outliers.R b/R/tm_outliers.R
index 54fad2527..bcfde2215 100644
--- a/R/tm_outliers.R
+++ b/R/tm_outliers.R
@@ -441,7 +441,7 @@ srv_outliers <- function(id, data, reporter, filter_panel_api, outlier_var,
anl_merged_input <- reactive({
dataname_first <- names(data())[[1]]
join_keys <- teal.data::join_keys(data())[dataname_first, dataname_first]
-
+
if (length(join_keys) == 0) {
# No join keys - create simple assignment expression
list(
@@ -638,7 +638,7 @@ srv_outliers <- function(id, data, reporter, filter_panel_api, outlier_var,
# ANL_OUTLIER_EXTENDED is the base table
join_keys <- as.character(teal.data::join_keys(data())[dataname_first, dataname_first])
-
+
if (length(join_keys) == 0) {
# No join keys - no join needed
qenv <- teal.code::eval_code(qenv, quote(ANL_OUTLIER_EXTENDED <- ANL_OUTLIER))
From 93b1674cee35af942d3217e708b03e9f816fe9f3 Mon Sep 17 00:00:00 2001
From: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
Date: Fri, 4 Jul 2025 14:13:34 +0000
Subject: [PATCH 10/16] [skip roxygen] [skip vbump] Roxygen Man Pages Auto
Update
---
man/tm_outliers.Rd | 50 +---------------------------------------------
1 file changed, 1 insertion(+), 49 deletions(-)
diff --git a/man/tm_outliers.Rd b/man/tm_outliers.Rd
index 1e3683fcb..f8c15278d 100644
--- a/man/tm_outliers.Rd
+++ b/man/tm_outliers.Rd
@@ -102,49 +102,6 @@ To learn more please refer to the vignette
\examples{
-# simple data example without join keys
-data <- teal_data()
-data <- within(data, {
- CO2 <- CO2
-})
-
-vars <- choices_selected(variable_choices(data[["CO2"]], c("Plant", "Type", "Treatment")))
-
-app <- init(
- data = data,
- modules = modules(
- tm_outliers(
- outlier_var = list(
- data_extract_spec(
- dataname = "CO2",
- select = select_spec(
- label = "Select variable:",
- choices = variable_choices(data[["CO2"]], c("conc", "uptake")),
- selected = "uptake",
- multiple = FALSE,
- fixed = FALSE
- )
- )
- ),
- categorical_var = list(
- data_extract_spec(
- dataname = "CO2",
- filter = filter_spec(
- vars = vars,
- choices = value_choices(data[["CO2"]], vars$selected),
- selected = value_choices(data[["CO2"]], vars$selected),
- multiple = TRUE
- )
- )
- )
- )
- )
-)
-if (interactive()) {
- shinyApp(app$ui, app$server)
-}
-
-
# general data example
data <- teal_data()
data <- within(data, {
@@ -240,16 +197,11 @@ if (interactive()) {
\section{Examples in Shinylive}{
\describe{
\item{example-1}{
- \href{https://shinylive.io/r/app/#code=NobwRAdghgtgpmAXGKAHVA6ASmANGAYwHsIAXOMpMAGwEsAjAJykYE8AKcqajGIgEwCu1OAGcMAcwpxm1AJQAdCLTIyoBUrQBucAAQAeALS6AZoIgbaJdnN0AVLAFUAokrcQAxLtG0YqEbr8UKRQunAAHrD+egDutKQAFkSCpLoAVkQqugDWcKyiSkEhBsZc1AD6RVA2hcGhRrpxiSrsVbi6IEq6ugDCAPIATCW9g0oAvooQSlososMESbQEYuWicCIacPzsM4y0UPQi5QuZy6KtdcDACmD9AzcAug-tBOw3AArUUGQ37Td2rFQcF+un+jDgwXgPzAclh7jQqGGKnibwg3SqugAvIE6rguro+EIRHNsYThGJUd1uqQYOVkqQ6DJzviqbp6YzGOVdljdHRRKRKayqVVyhFSMwNKsga8WUL0XVoPAeTc7r9ZXK1htUtjNXBJaJpYK5ayvvR1sqwABldZ61K7faHOCINVo42sk5LMQ8+0HI4es4XEJXFWjMBPF5vQgkAggm6CVAhXI3WF411u7q6zb8C3xxPAvDq40wYSaaI8gBiAEEADKW5yp9NUky0cJbCs1uuF1mTN09oVyBtCgjBOASIh7YcVbnYvkCrs4kKi8Li9SkKV6o3GqqKvTYkP3Atp43N6jkRg8k9n9cyo9u3Yk3T3weN-1e7EzaiCODHRYBqrB25Q3DR9ZgAEkzch+AHedWQgtt324L8f1OCl-2uQCD2A+9wJtLNoNvIsS1oMtsQcFwYN0Ps5SoqkaL7SZJloExdHYFQz1XbQ4BsWxOldUQEhUVhK3QdgEVAwRaHaMS1kYHRGEmMYlDAMYHiAA}{Open in Shinylive}
- \if{html}{\out{}}
- \if{html}{\out{}}
- }
- \item{example-2}{
\href{https://shinylive.io/r/app/#code=NobwRAdghgtgpmAXGKAHVA6ASmANGAYwHsIAXOMpMAGwEsAjAJykYE8AKcqajGIgEwCu1OAGcMAcwpxm1AJQAdCLTIyoBUrQBucAAQAeALS6AZoIgbaJdnN0AVLAFUAokrcQAxLqkQ11XfxQpFC6cAAesKgiSoHBBsZc1AD6sVA2MUEhRroA7rSkABYq7Km4uiBKuroAwgDyAEzxNQ2VzfXAwApgqIy0MCysSQDWcKxdALrjTaJwAI5JIhDsEIxEOex19XKKEAC+OwBWRCrDo6IlmbbZRycjrOc3EKccXZtdZa8teLpdPX0Dzy623cWhYoiaBAKxwIYiSMxEGjg-HYoN6UHoIiSkOhYguwQ6n3qE3GZQI7C6AAVqFAyO8fmA7KxUHA6V07Iw4EF4LSwNsdko0Kgmip8uSIFVUroALwBTK4Vp8IQicEyxXCXGtKqkGBJIiCUh0GTnTVVXR6g20GRJVHS3R0USkMWm52y4JJcKkZgaOHMskml2ummwPQywnvf0u+FwDS2qPe0S+p0Bl3U+hwfyhsAAZXT0dIulRtHRIkQ4fFyed2NoMJVBZYRYxcCxUOruNSBLAbzAk1J5MIJAIrLAglQwRGQLk8vLFaqcfI-FtXRHY5ZeAjAZgwk0URDugAYgBBAAyWecU5nppMtDCSNth5PrmnyZ2FZfLsnEYIQTgEiIvS-yQ2jK9qOuugbumEnrqKQPrRkmFapNA8CLp2XznjOV7UOQjC2ph2GwX6T4VqitYkehF5VjWtqgtQghNpRbaZB2XY9nWjCiAAJHOSIfkRybcQuMo0XRzY4uc7adKhRLdiSbGcQJvEXlUm5YbQO62g4LhgVUb4Brppr6W+Ow7LQJi6OwKjYdB2hwDYtgVOWohFBArAHug7CChxgi0GUnkzIwOiMDsuxKGAuzjEAA}{Open in Shinylive}
\if{html}{\out{}}
\if{html}{\out{}}
}
- \item{example-3}{
+ \item{example-2}{
\href{https://shinylive.io/r/app/#code=NobwRAdghgtgpmAXGKAHVA6ASmANGAYwHsIAXOMpMAGwEsAjAJykYE8AKcqajGIgEwCu1OAGcMAcwpxm1AJQAdCLTIyoBUrQBucAAQAeALS6AZoIgbaJdnN0AVLAFUAokrcQAxLoDCAEQCSAMreuvxQpFC6cAAesKgiSmERBsZc1AD6SVA2ieGRRroA7rSkABYq7Fm4uiBKuroAgr6BADIpumkYWYiIjE2tSgC+ihAAVkQq6QDWcKyilXm2BfxwJlDCpOkE-LSiBOnjkzNzwNDw81lyALruaxrpWiyi6VD8otTtZ2LsAGK01ORGOxdg4XNVRGh4hwssBgAowP0WvCrldqrsMHdSERGHJcUpHoxRO0CKUJgQxOlRHARBo4Px2ATaFB6CItqTaOSLnlYfDEcjUaZ1JsCc9Xu88RB3EpIe0VCV2HVQnldABeJURXCKvhCEREtXa4TfRX1UgwdJEQSkOgyebG+q6C1W2gyB4sVW6OiiUgKiD2v3qqDpGKkZj3USoOAEH3+-1ZL7u3nNJF4O0xqk00ju9ORzbhyPRmP+6jM6kJsCBak53SM5kiRDwzW+wt+klksTumssuBsttciI8hFJ-nVKO8gDirjwunhACEALJYADSWAAjPDcY3m37s7T+GWGhOG6nCzANrR4no1T8Gi1As5N1v6iZaNE6e7r7fXE3myMf8e5A+LbhHAEjYhy3Cuow7qet6x71FkQbRCGQqUhGo7foWcawJe06DgMKYYTGz4AjI7rEYCqH5nB-oih2TyAVurYcu2aqPNQgjdkxnILP2cJ4cmKLVCKAAkO7kPwAHUdula7nR7Gcey3EwnxfJgIJ1ZPKJMniZJhEnmeF7uqCX6Pr+hZmX6Fm6GZIwjLQJi6MCqihpoOg2LYtRNqI5QQKwDToOwkLCYItDVEFVKMDoOJDEoYCDFcQA}{Open in Shinylive}
\if{html}{\out{}}
\if{html}{\out{}}
From f3a88e49d2ef9b00f571379f5a9b688f2251da5e Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 4 Jul 2025 14:25:04 +0000
Subject: [PATCH 11/16] Simplify tm_outliers fix - use minimal conditional
logic to avoid merge_expression_srv when no join keys exist
Co-authored-by: m7pr <133694481+m7pr@users.noreply.github.com>
---
R/tm_outliers.R | 47 ++++++++++++++++++++---------------------------
1 file changed, 20 insertions(+), 27 deletions(-)
diff --git a/R/tm_outliers.R b/R/tm_outliers.R
index bcfde2215..0bb69ebee 100644
--- a/R/tm_outliers.R
+++ b/R/tm_outliers.R
@@ -441,9 +441,10 @@ srv_outliers <- function(id, data, reporter, filter_panel_api, outlier_var,
anl_merged_input <- reactive({
dataname_first <- names(data())[[1]]
join_keys <- teal.data::join_keys(data())[dataname_first, dataname_first]
-
+
if (length(join_keys) == 0) {
- # No join keys - create simple assignment expression
+ # No join keys - single dataset, no merging needed
+ # Return the same structure as merge_expression_srv but with simple assignment
list(
expr = substitute(ANL <- dataname, list(dataname = as.name(dataname_first))),
columns_source = list(
@@ -456,7 +457,7 @@ srv_outliers <- function(id, data, reporter, filter_panel_api, outlier_var,
)
)
} else {
- # Join keys exist - use standard merge
+ # Join keys exist - use merge_expression_srv
teal.transform::merge_expression_srv(
selector_list = reactive_select_input,
datasets = data,
@@ -637,33 +638,25 @@ srv_outliers <- function(id, data, reporter, filter_panel_api, outlier_var,
)
# ANL_OUTLIER_EXTENDED is the base table
- join_keys <- as.character(teal.data::join_keys(data())[dataname_first, dataname_first])
-
- if (length(join_keys) == 0) {
- # No join keys - no join needed
- qenv <- teal.code::eval_code(qenv, quote(ANL_OUTLIER_EXTENDED <- ANL_OUTLIER))
- } else {
- # Join keys exist - perform left join
- qenv <- teal.code::eval_code(
- qenv,
- substitute(
- expr = {
- ANL_OUTLIER_EXTENDED <- dplyr::left_join(
- ANL_OUTLIER,
- dplyr::select(
- dataname,
- dplyr::setdiff(names(dataname), dplyr::setdiff(names(ANL_OUTLIER), join_keys))
- ),
- by = join_keys
- )
- },
- env = list(
- dataname = as.name(dataname_first),
- join_keys = join_keys
+ qenv <- teal.code::eval_code(
+ qenv,
+ substitute(
+ expr = {
+ ANL_OUTLIER_EXTENDED <- dplyr::left_join(
+ ANL_OUTLIER,
+ dplyr::select(
+ dataname,
+ dplyr::setdiff(names(dataname), dplyr::setdiff(names(ANL_OUTLIER), join_keys))
+ ),
+ by = join_keys
)
+ },
+ env = list(
+ dataname = as.name(dataname_first),
+ join_keys = as.character(teal.data::join_keys(data())[dataname_first, dataname_first])
)
)
- }
+ )
qenv <- if (length(categorical_var) > 0) {
qenv <- teal.code::eval_code(
From e8589def13ea131dc6eafd77a88c8ef89ef85e52 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 4 Jul 2025 14:27:15 +0000
Subject: [PATCH 12/16] Fix ANL_OUTLIER_EXTENDED join logic to handle missing
join keys
Co-authored-by: m7pr <133694481+m7pr@users.noreply.github.com>
---
R/tm_outliers.R | 40 ++++++++++++++++++++++++----------------
1 file changed, 24 insertions(+), 16 deletions(-)
diff --git a/R/tm_outliers.R b/R/tm_outliers.R
index 0bb69ebee..8ba1ffe4f 100644
--- a/R/tm_outliers.R
+++ b/R/tm_outliers.R
@@ -638,25 +638,33 @@ srv_outliers <- function(id, data, reporter, filter_panel_api, outlier_var,
)
# ANL_OUTLIER_EXTENDED is the base table
- qenv <- teal.code::eval_code(
- qenv,
- substitute(
- expr = {
- ANL_OUTLIER_EXTENDED <- dplyr::left_join(
- ANL_OUTLIER,
- dplyr::select(
- dataname,
- dplyr::setdiff(names(dataname), dplyr::setdiff(names(ANL_OUTLIER), join_keys))
- ),
- by = join_keys
+ join_keys <- as.character(teal.data::join_keys(data())[dataname_first, dataname_first])
+
+ if (length(join_keys) == 0) {
+ # No join keys - single dataset, no join needed
+ qenv <- teal.code::eval_code(qenv, quote(ANL_OUTLIER_EXTENDED <- ANL_OUTLIER))
+ } else {
+ # Join keys exist - perform left join
+ qenv <- teal.code::eval_code(
+ qenv,
+ substitute(
+ expr = {
+ ANL_OUTLIER_EXTENDED <- dplyr::left_join(
+ ANL_OUTLIER,
+ dplyr::select(
+ dataname,
+ dplyr::setdiff(names(dataname), dplyr::setdiff(names(ANL_OUTLIER), join_keys))
+ ),
+ by = join_keys
+ )
+ },
+ env = list(
+ dataname = as.name(dataname_first),
+ join_keys = join_keys
)
- },
- env = list(
- dataname = as.name(dataname_first),
- join_keys = as.character(teal.data::join_keys(data())[dataname_first, dataname_first])
)
)
- )
+ }
qenv <- if (length(categorical_var) > 0) {
qenv <- teal.code::eval_code(
From 8390f9c1bdd35f49bbc3bb1e29e7535d5faccc05 Mon Sep 17 00:00:00 2001
From: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
Date: Mon, 7 Jul 2025 09:51:58 +0000
Subject: [PATCH 13/16] [skip style] [skip vbump] Restyle files
---
R/tm_outliers.R | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/R/tm_outliers.R b/R/tm_outliers.R
index 8ba1ffe4f..b26ef24ae 100644
--- a/R/tm_outliers.R
+++ b/R/tm_outliers.R
@@ -441,7 +441,7 @@ srv_outliers <- function(id, data, reporter, filter_panel_api, outlier_var,
anl_merged_input <- reactive({
dataname_first <- names(data())[[1]]
join_keys <- teal.data::join_keys(data())[dataname_first, dataname_first]
-
+
if (length(join_keys) == 0) {
# No join keys - single dataset, no merging needed
# Return the same structure as merge_expression_srv but with simple assignment
@@ -639,7 +639,7 @@ srv_outliers <- function(id, data, reporter, filter_panel_api, outlier_var,
# ANL_OUTLIER_EXTENDED is the base table
join_keys <- as.character(teal.data::join_keys(data())[dataname_first, dataname_first])
-
+
if (length(join_keys) == 0) {
# No join keys - single dataset, no join needed
qenv <- teal.code::eval_code(qenv, quote(ANL_OUTLIER_EXTENDED <- ANL_OUTLIER))
From be9ceff3f6214bee9aa24f9339f4550c2d9c381e Mon Sep 17 00:00:00 2001
From: m7pr
Date: Wed, 9 Jul 2025 13:16:50 +0200
Subject: [PATCH 14/16] simplify approach to create dummy join_keys
---
R/tm_outliers.R | 31 +++++++++++--------------------
1 file changed, 11 insertions(+), 20 deletions(-)
diff --git a/R/tm_outliers.R b/R/tm_outliers.R
index b26ef24ae..dd7a08b34 100644
--- a/R/tm_outliers.R
+++ b/R/tm_outliers.R
@@ -441,29 +441,20 @@ srv_outliers <- function(id, data, reporter, filter_panel_api, outlier_var,
anl_merged_input <- reactive({
dataname_first <- names(data())[[1]]
join_keys <- teal.data::join_keys(data())[dataname_first, dataname_first]
+ obj <- data()
if (length(join_keys) == 0) {
- # No join keys - single dataset, no merging needed
- # Return the same structure as merge_expression_srv but with simple assignment
- list(
- expr = substitute(ANL <- dataname, list(dataname = as.name(dataname_first))),
- columns_source = list(
- outlier_var = reactive_select_input()$outlier_var()$select,
- categorical_var = if (!is.null(reactive_select_input()$categorical_var)) {
- names(reactive_select_input()$categorical_var()$filter)
- } else {
- character(0)
- }
- )
- )
- } else {
- # Join keys exist - use merge_expression_srv
- teal.transform::merge_expression_srv(
- selector_list = reactive_select_input,
- datasets = data,
- merge_function = "dplyr::inner_join"
- )()
+ if (!".row_id" %in% names(obj[[dataname_first]])) {
+ obj[[dataname_first]]$.row_id <- seq_len(nrow(obj[[dataname_first]]))
+ }
+ join_keys(obj) <- join_keys(join_key(dataname_first, dataname_first, ".row_id"))
}
+
+ teal.transform::merge_expression_srv(
+ selector_list = reactive_select_input,
+ datasets = reactive(obj),
+ merge_function = "dplyr::inner_join"
+ )()
})
anl_merged_q <- reactive({
From db981e45831d326aa039be02100888e33f04462b Mon Sep 17 00:00:00 2001
From: m7pr
Date: Wed, 9 Jul 2025 13:27:31 +0200
Subject: [PATCH 15/16] fix second join
---
R/tm_outliers.R | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/R/tm_outliers.R b/R/tm_outliers.R
index dd7a08b34..0ea4bfdc5 100644
--- a/R/tm_outliers.R
+++ b/R/tm_outliers.R
@@ -442,7 +442,7 @@ srv_outliers <- function(id, data, reporter, filter_panel_api, outlier_var,
dataname_first <- names(data())[[1]]
join_keys <- teal.data::join_keys(data())[dataname_first, dataname_first]
obj <- data()
-
+
if (length(join_keys) == 0) {
if (!".row_id" %in% names(obj[[dataname_first]])) {
obj[[dataname_first]]$.row_id <- seq_len(nrow(obj[[dataname_first]]))
@@ -631,8 +631,8 @@ srv_outliers <- function(id, data, reporter, filter_panel_api, outlier_var,
# ANL_OUTLIER_EXTENDED is the base table
join_keys <- as.character(teal.data::join_keys(data())[dataname_first, dataname_first])
- if (length(join_keys) == 0) {
- # No join keys - single dataset, no join needed
+ if (length(join_keys) == 1 && join_keys == ".row_id") {
+ # Dummy join key - single dataset, no join needed
qenv <- teal.code::eval_code(qenv, quote(ANL_OUTLIER_EXTENDED <- ANL_OUTLIER))
} else {
# Join keys exist - perform left join
From 31362b9ae00493c36e98420ad5446cc8d41b2fdd Mon Sep 17 00:00:00 2001
From: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
Date: Wed, 9 Jul 2025 11:30:07 +0000
Subject: [PATCH 16/16] [skip style] [skip vbump] Restyle files
---
R/tm_outliers.R | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/R/tm_outliers.R b/R/tm_outliers.R
index 0ea4bfdc5..586e3f330 100644
--- a/R/tm_outliers.R
+++ b/R/tm_outliers.R
@@ -442,7 +442,7 @@ srv_outliers <- function(id, data, reporter, filter_panel_api, outlier_var,
dataname_first <- names(data())[[1]]
join_keys <- teal.data::join_keys(data())[dataname_first, dataname_first]
obj <- data()
-
+
if (length(join_keys) == 0) {
if (!".row_id" %in% names(obj[[dataname_first]])) {
obj[[dataname_first]]$.row_id <- seq_len(nrow(obj[[dataname_first]]))