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

Transformer called too early #1478

Merged
merged 7 commits into from
Feb 6, 2025
Merged

Transformer called too early #1478

merged 7 commits into from
Feb 6, 2025

Conversation

gogonzo
Copy link
Contributor

@gogonzo gogonzo commented Feb 4, 2025

closes #1473

Call of the custom transformer is postponed until the data from the previous stage (filter-panel, previous transformer, previous decorator, module-data) is ok.

@gogonzo gogonzo added the core label Feb 4, 2025
@gogonzo gogonzo changed the title fix Transformer called too early Feb 4, 2025
Copy link
Contributor

github-actions bot commented Feb 4, 2025

Unit Tests Summary

  1 files   27 suites   10m 51s ⏱️
274 tests 270 ✅ 4 💤 0 ❌
534 runs  530 ✅ 4 💤 0 ❌

Results for commit f78f9e8.

♻️ This comment has been updated with latest results.

Copy link
Contributor

github-actions bot commented Feb 4, 2025

Unit Test Performance Difference

Test Suite $Status$ Time on main $±Time$ $±Tests$ $±Skipped$ $±Failures$ $±Errors$
module_session_info 💚 $18.24$ $-1.08$ $0$ $0$ $0$ $0$
module_teal 💚 $139.52$ $-2.26$ $0$ $0$ $0$ $0$
shinytest2-data_summary 💚 $55.48$ $-1.78$ $0$ $0$ $0$ $0$
shinytest2-filter_panel 💚 $44.47$ $-2.23$ $0$ $0$ $0$ $0$
shinytest2-init 💚 $30.29$ $-2.01$ $0$ $0$ $0$ $0$
shinytest2-landing_popup 💚 $50.08$ $-2.65$ $0$ $0$ $0$ $0$
shinytest2-module_bookmark_manager 💚 $39.24$ $-2.23$ $0$ $0$ $0$ $0$
shinytest2-modules 💚 $43.13$ $-3.33$ $0$ $0$ $0$ $0$
shinytest2-reporter 💚 $70.17$ $-1.79$ $0$ $0$ $0$ $0$
shinytest2-teal_data_module 💚 $49.01$ $-1.07$ $0$ $0$ $0$ $0$
shinytest2-teal_slices 💚 $63.09$ $-2.07$ $0$ $0$ $0$ $0$
shinytest2-wunder_bar 💚 $24.15$ $-1.48$ $0$ $0$ $0$ $0$
Additional test case details
Test Suite $Status$ Time on main $±Time$ Test Case
module_session_info 💚 $18.22$ $-1.08$ creation_process_is_invoked_for_teal.lockfile.mode_enabled_and_snapshot_is_copied_to_teal_app.lock_and_removed_after_session_ended
shinytest2-modules 💚 $11.13$ $-1.61$ e2e_the_module_server_logic_is_only_triggered_when_the_teal_module_becomes_active
shinytest2-teal_slices 💚 $38.50$ $-1.21$ e2e_teal_slices_filters_are_initialized_when_module_specific_filters_are_created

Results for commit 1e3ef61

♻️ This comment has been updated with latest results.

@gogonzo gogonzo marked this pull request as draft February 4, 2025 07:52
@gogonzo gogonzo marked this pull request as ready for review February 4, 2025 10:21
@vedhav
Copy link
Contributor

vedhav commented Feb 6, 2025

It works as expected. There is just a minor difference now, when the transformers are initiated and one of the transformator does not return anything, we used to get a warning in the subsequent transformers and now we do not get this.
Screenshot 2025-02-06 at 3 41 36 PM
Screenshot 2025-02-06 at 3 43 01 PM

Example to reproduce
devtools::load_all()

data <- within(teal_data(), {
  iris <- iris
  mtcars <- mtcars
})

make_data <- function(datanames = c("ADSL", "ADTTE")) {
  data_obj <- teal.data::teal_data()
  if ("ADSL" %in% datanames) {
    data_obj <- within(data_obj, ADSL <- teal.data::rADSL)
  }
  if ("ADTTE" %in% datanames) {
    data_obj <- within(data_obj, ADTTE <- teal.data::rADTTE)
  }
  join_keys(data_obj) <- default_cdisc_join_keys[datanames]
  teal.data::datanames(data_obj) <- datanames
  data_obj
}

transformators <- list(
  teal_transform_module(
    label = "test",
    ui = function(id) {
      ns <- NS(id)
      tagList(
        selectizeInput(
          ns("errortype"),
          label = "Error Type",
          choices = c(
            "ok", "insufficient datasets", "no data",
            "qenv.error", "error in reactive", "validate error", "silent.shiny.error", "not a reactive"
          )
        ),
        actionButton(ns("submit"), "Go!")
      )
    },
    server = function(id, data) {
      moduleServer(id, function(input, output, session) {
        logger::log_trace("example_module_transform2 initializing.")
        eventReactive(input$submit, {
          switch(input$errortype,
            ok = make_data(),
            `insufficient datasets` = make_data(datanames = "ADSL"),
            `no data` = teal_data(),
            qenv.error = within(data(), stop("\nthis is qenv.error in teal_data_module\n")),
            `error in reactive` = stop("\nerror in a reactive in teal_data_module\n"),
            `validate error` = validate(need(FALSE, "\nvalidate error in teal_data_module\n")),
            `silent.shiny.error` = req(FALSE)
          )
        })
      })
    }
  ),
  teal_transform_module(
    label = "Custom transformator for iris",
    ui = function(id) {
      ns <- NS(id)
      tags$div(
        uiOutput(ns("n_rows_ui"))
      )
    },
    server = function(id, data) {
      moduleServer(id, function(input, output, session) {
        output$n_rows_ui <- renderUI({
          numericInput(
            session$ns("n_rows"),
            "Number of rows to subset",
            value = 6, min = 1, max = 150, step = 1
          )
        })
        reactive({
          within(data(),
            {
              iris <- head(iris, num_rows)
            },
            num_rows = input$n_rows
          )
        })
      })
    }
  ),
  teal_transform_module(
    label = "Scaling transformator for iris 1",
    ui = function(id) {
      ns <- NS(id)
      uiOutput(ns("scaled_columns_container"))
    },
    server = function(id, data) {
      moduleServer(id, function(input, output, session) {
        ns <- session$ns

        # scalable_columns <- names(Filter(is.numeric, isolate(data())[["iris"]]))
        scalable_columns <- names(Filter(is.numeric, isolate(data())[["iris"]]))


        output$scaled_columns_container <- renderUI({
          selectInput(
            inputId = ns("scaled_columns"),
            label = "Columns to scale",
            choices = scalable_columns,
            selected = scalable_columns[1],
            multiple = TRUE
          )
        })

        new_data <- reactive({
          if (length(input$scaled_columns)) {
            data() |>
              within(
                {
                  iris <- iris |> dplyr::select(dplyr::all_of(scaled_columns))
                },
                scaled_columns = input$scaled_columns
              )
          } else {
            data()
          }
        })

        reactive({
          new_data()
        })
      })
    }
  )
)

app <- init(
  data = data,
  modules = teal::example_module(transformators = transformators)
)

shinyApp(app$ui, app$server)

Copy link
Contributor

@vedhav vedhav left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified the fix works. The minor difference is only when the transformator does not return a reactive teal_data (which is not the way to use transformators) so approving.

@gogonzo gogonzo merged commit 4bd73cf into main Feb 6, 2025
28 checks passed
@gogonzo gogonzo deleted the 1473_trigger_transform_on_data branch February 6, 2025 11:22
@github-actions github-actions bot locked and limited conversation to collaborators Feb 6, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug]: Transformers initiate without access to data.
3 participants