(Going crazy) How can I make my plot explicitly reference a specific piece of my reactive?

I have a shiny app that has a very large reactive performing many functions from a user input. Here I make a very minimal reproducible example to explain my problem.

This is a simple Shiny app that lets a user type something into a text box. It will take this input and behind the scenes make two data frames, one with a "+1" added, the other with "+2" added.

Currently, it only returns the "+1" version, because the reactive code has the line return(result1). However, there are 2 data frames here.

How could I make a second renderDataTable function that returns the result2 data frame?

If I change return(result1) to return(result2) it will then only return result2. I'm looking for a way to explicitly reference this, like renderDataTable(my_reactive(result2)) - but that isn't working.

library(shiny)

# Define UI-
ui <- fluidPage(
  sidebarLayout(
    
    #User can input anything into a textbox
    textInput(inputId = "value", label = "value", value="")
    ,
    
    #Displays the result
    mainPanel(
      dataTableOutput("value")
    )))

# Define server logic
server <- function(input, output) {

#A reactive that takes the input, turns it into a data frame, and appends "+1" or "+2"
my_reactive <- reactive({
  req(input$value)
  result1 <- data.frame("result"=input$value)
  result1$result <- paste0(result1, "+1")

  result2 <- data.frame("result"=input$value)
  result2$result <- paste0(result2, "+2")
  
  return(result1)

})  

#Return the final result as a data frame
output$value <- renderDataTable(my_reactive(), #HOW can I explicitly reference 'result1' or 'result2' here??
                                 rownames=FALSE,
                                 options = list(
                                   columnDefs = list(
                                     list(className = 'dt-center', targets="_all")),
                                   scrollX=TRUE,
                                   #scrollY="100px",
                                   lengthChange=FALSE,
                                   paging=FALSE,
                                   searching=FALSE,
                                   ordering=FALSE,
                                   dom='ft'
                                 )) #End of options)
  
}
# Run the app ----
shinyApp(ui, server)

I think you can have my_reactive return a list and have to renderDataTable functions that are passed elements of that list.

my_reactive <- reactive({
  req(input$value)
  result1 <- data.frame("result"=input$value)
  result1$result <- paste0(result1, "+1")

  result2 <- data.frame("result"=input$value)
  result2$result <- paste0(result2, "+2")
  
  return(list(R1 = result1, R2 = result2)

})
output$value1 <- renderDataTable(my_reactive()$R1, ...

output$value2 <- renderDataTable(my_reactive()$R2, ...
1 Like

My mind is blown!! Thank you @FJCC !

You have saved me from making separate reactives for each thing I wanted to return/plot. This solution worked beautifully.

Thank you!

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.