Search code examples
rshinylapplyshiny-reactivityselectinput

How can I store the output using lapply in shiny?


I am building an app which allows the user to submit a formation of football players. The player names are stored in a .csv file. These names are read in and are then the input for the select inputs. The user is supposed to first select a formation and then depending on the selected formation the select inputs with the names appear. This works pretty well (in the example below with 2 select inputs) by using lapply.
My problem is now that I would like to store the selected names in a variable to further use them. The variable myval is supposed to store the selected name. It somehow only works with the first selected name of the first select input.

What I mean is that this works and stores the name selected in the first select input:

     myval <- eventReactive(input$i[1],
                                 {input$i[1]}) 

But this doesn't work:

     myval <- eventReactive(input$i[2],
                                 {input$i[2]}) 

Below you can find the full code. Many thanks in advance!

ui.R:

    fluidPage(
    #Dropdown
      selectInput("Formation", label = "Formation", choice = c("",433,343)),
    #Output
      uiOutput(outputId = "select_formation")
    )

server.R:


    function(input, output, session){
    
    #input_names <- read.csv("temp.csv",TRUE,";")
    input_names <- structure(list(Goalkeeper = c("-", "Max", "Mo", "Tobi", "", "", 
""), Defender = c("-", "Bob", "Julius", "Mat", "Hans", "Peter", 
"Tom")), class = "data.frame", row.names = c(NA, -7L))

    output$select_formation = renderUI(
        if(input$Formation == 433){      
          lapply(1:2,function(i){
          selectInput(inputId = "i", label = names(input_names[i]), choices = c(input_names[,i]))
          })
        })

      myval <- eventReactive(input$i[2],
                             {input$i[2]}) 
 }


Solution

  • Thanks for providing the data. Here is a working example that might be helpful.

    The inputId for the dynamically created selectInput is created by paste0("id", i) so you will have id1 and id2 in your example.

    Your myval reactive expression can obtain a list of the input values through lapply again, using the same ids for reference.

    library(shiny)
    
    ui <- fluidPage(
      selectInput("Formation", label = "Formation", choice = c("",433,343)),
      uiOutput(outputId = "select_formation"),
      uiOutput("select_inputs")
    )
    
    server <- function(input, output, session) {
      
      output$select_formation = renderUI(
        if(input$Formation == 433){      
          lapply(1:2, function(i){
            selectInput(inputId = paste0("id", i), label = names(input_names[i]), choices = c(input_names[i]))
          })
        })
      
      myval <- reactive({
        lapply(1:2, function(i) {
          input[[paste0("id", i)]]
        })
      })
                             
      output$select_inputs <- renderUI({
        paste("You selected: ", paste(myval(), collapse = ", "))
      })
      
    }
    
    shinyApp(ui, server)