insightsengineering / insightsengineering/teal.picks

[Bug]: fixed `variables()` choices + multi-`datasets()` breaks `merge_srv` after dataset switch

Open
#56 5 comments 0 reactions 0 assignees View on GitHub
bug core
Dominant language
R
Stars
4
Forks
0
Avg merge
6d 11h
Merged PRs (30d)
3

Description

### What happened?

When a `picks()` spec allows switching `datasets()` (e.g. `ADSL` vs `ADLB`) but `variables()` uses a fixed character vector of column names that exist on one table only (e.g. `PARAM`, `AVAL` on `ADLB)`, switching to the other dataset produces invalid merge code.

Evaluation then returns a `qenv.error`, and a later `join_keys<-` call surfaces as no applicable method for `'join_keys<-' ... 'qenv.error'`, which is misleading because the root failure is earlier (bad select / merge pipeline).

Reproduce with

```
library(shiny)
library(teal.data)
library(teal.picks)

merge_reprex_data <- function() {
data <- teal_data()
data <- within(data, {
ADSL <- data.frame(
USUBJID = sprintf("S%03d", 1:8),
AGE = sample(35:70, 8, replace = TRUE),
stringsAsFactors = FALSE
)
ADLB <- data.frame(
USUBJID = rep(sprintf("S%03d", 1:8), each = 3),
PARAM = rep(c("ALT", "AST", "BILI"), 8),
AVAL = round(rnorm(24, 42, 6), 1),
stringsAsFactors = FALSE
)
})
join_keys(data) <- join_keys(teal.data::join_key("ADSL", "ADLB", keys = "USUBJID"))
data
}

merge_reprex_picks_broken <- function() {
picks(
datasets(choices = c("ADSL", "ADLB"), selected = "ADLB"),
variables(
choices = c("PARAM", "AVAL"),
selected = c("PARAM", "AVAL"),
multiple = TRUE
)
)
}

merge_reprex_picks_working <- function() {
picks(
datasets(choices = c("ADSL", "ADLB"), selected = "ADLB"),
variables(
choices = tidyselect::everything(),
selected = c(1L, 2L),
multiple = TRUE
)
)
}

merge_reprex_make_app <- function(picks, title) {
cached_data <- merge_reprex_data()
data_r <- reactive({
cached_data
})

ui <- fluidPage(
titlePanel(title),
fluidRow(
column(4, picks_ui("sel", picks = picks)),
column(
8,
tags$h4("Mapped"),
verbatimTextOutput("mapped"),
tags$h4("Merge preview (error text or str of anl)"),
verbatimTextOutput("merged")
)
)
)

server <- function(input, output, session) {
selectors <- list(sel = picks_srv("sel", picks = picks, data = data_r))
merged <- merge_srv("merge", data = data_r, selectors = selectors)

output$mapped <- renderPrint({
yaml::as.yaml(merged$variables())
})

output$merged <- renderPrint({
shiny::req(merged$data())
td <- merged$data()
if (inherits(td, "qenv.error")) {
return(conditionMessage(td))
}
str(td[["anl"]], max.level = 1L)
})
}

shinyApp(ui, server)
}

run_merge_reprex_broken <- function() {
shiny::runApp(
merge_reprex_make_app(
merge_reprex_picks_broken(),
"Broken: variables(PARAM, AVAL) — switch dataset to ADSL"
),
launch.browser = TRUE
)
}

run_merge_reprex_working <- function() {
shiny::runApp(
merge_reprex_make_app(
merge_reprex_picks_working(),
"Working: tidyselect::everything(), selected = c(1L, 2L)"
),
launch.browser = TRUE
)
}
run_merge_reprex_broken() # opens app: switch dataset ADLB → ADSL → merge preview errors
run_merge_reprex_working() # opens app: same UI pattern, delayed variables — OK when switching

```

### Relevant log output

_No response_

### Code of Conduct

- [x] I agree to follow this project's Code of Conduct.

### Contribution Guidelines

- [x] I agree to follow this project's Contribution Guidelines.

### Security Policy

- [x] I agree to follow this project's Security Policy.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.