Search code examples
rshinyreactivegtsummarygt

r shiny {gtsummary} by= argument reactive from a second SelectInput


Come so far: r shiny reactive gt_summary table

I would like to have a gtsummary table with selected variables from an SelectInput field in a reactive manner (Input$y). This is already achieved. Now I would like to choose the by= argument for gtsummary from a second reactive SelectInput field (Input$x). Tried a lot but without success. Thanks for any help.

My code:

library(shiny)
library(gtsummary)
library(gt)
# make dataset with a few variables to summarize
iris2 <- iris %>% select(Sepal.Length,  Sepal.Width, Species)
# add fake factor column 
iris2 <- iris2 %>% 
  mutate(Species_1 = Species)


shinyApp(
  ui = fluidPage(
    fluidRow(
      column(12,
             # Select variable to analyze
             selectInput(inputId = "y", 
                         label = "Y-Variable:", 
                         choices = c("Sepal Length" ="Sepal.Length",
                                    "Sepal Width" = "Sepal.Width"),
                         selected = "Sepal.Length"),
             
             # select factor variable
             selectInput(inputId = "x",
                         label = "Factor:",
                         choices = c("Species" = "Species", 
                                   "Other Species" = "Species_1"),
                         selected = "Species"),
             
             gt_output('table')
      )
    )
  ),
  server = function(input, output) {

    varY <- reactive({
      input$y
      })
    varX <- reactive({
      input$x
      })
    
    output$table <- render_gt({
      
      table1 <- iris2 %>% select(iris2, all_of(varY())) %>%
        tbl_summary(by = varX()) %>%
        add_p(pvalue_fun = ~style_pvalue(.x, digits = 2)) %>% as_gt()
  })
      
}) 

Solution

  • This could be achieved like so:

    1. You duplicated the name of the dataset, i.e. iris2 %>% select(iris2, all_of(varY())) should be simply iris2 %>% select(all_of(varY()))

    2. You also have to select the by variable, i.e. select(all_of(c(varY(), varX())))

    3. Passing the reactive function directly to by gives an error. Therefore I added an auxilliary variable by which I pass to the by argument of tbl_summary.

      output$table <- render_gt({
        by <- varX()
        table1 <- iris2 %>% 
          select(all_of(c(varY(), by))) %>%
          tbl_summary(by = by) %>%
          add_p(pvalue_fun = ~style_pvalue(.x, digits = 2)) %>% as_gt()
      })