1

This post is an extension of a previous post where I accidentally oversimplified my sample code to replicate the issue. I am trying to repetitively create variables for use in shiny, depending on how many fields a user selects in an input field. The answer that was provided was more than suitable and I am looking to expand on it. The oversimplification of the last post was the use of a numericInput to determine the number of fields to generate, when I actually need to count how many entries are selected of a selectInput to determine how many fields to populate. I then need to reiteratively call upon those generated fields in the server to generate the outputs. My sample code for attempting to expand on this issue is below.

my_letters <- c("A", "B", "C", "D", "E", "F", "G", "H", "I", "J")
my_names <- c("Mary", "Joe", "John", "Steve", "Bob", "Linda", "Emily", "Kevin", "Michael", "Tom")
my_number <- as.character(1:10)
my_df <- data.frame(my_letters, my_names, my_number)

letter_choices <- as.character(unique(my_df$my_letters))

ui <- fluidPage(
  selectInput("num_selected", label = "Select Letters", choices = letter_choices, selected = "", multiple = TRUE, selectize = TRUE),
  uiOutput("condPanels")
)

server<-function(input,output,session){

  output$condPanels <- renderUI({
    # if selected value = 0 dont create a condPanel,...
    if(!nrow(input$num_selected)) return(NULL)
    tagList(
      lapply(1:nrow(input$num_selected), function(nr){
        conditionalPanel(
          condition = paste0("input.num_selected >= ", nr),
          textOutput(paste0("Name", nr), "Name"),
          textOutput(paste0("Number", nr), "Number")

        )
      })
    ) 
  })

  output$Name1 <- renderText({ as.character(my_df$my_names[1]) })
  output$Name2 <- renderText({ as.character(my_df$my_names[2]) })

  output$Number1 <- renderText({ as.character(my_df$my_number[1]) })
  output$Number2 <- renderText({ as.character(my_df$my_number[2]) })

}

shinyApp(ui=ui, server=server) 
2
  • so you want textOutput() instead of textInput() ? That would indeed be a bit different ;) So no conditional inputs as well? Commented Jun 12, 2017 at 18:05
  • output$condPanels <- renderUI({ # if selected value = 0 dont create a condPanel,... if (length(input$num_selected) == 0) return(NULL) tagList( lapply(1:length(input$num_selected), function(nr){ conditionalPanel( condition = "input.num_selected", textOutput(paste0("Name", nr)), textOutput(paste0("Number", nr)) ) }) ) }) Commented Jun 12, 2017 at 18:16

1 Answer 1

2

You could do it without the conditional panel like this. The output can you define via output[["name"]] in case you also want that dynamic,..

my_letters <- c("A", "B", "C", "D", "E", "F", "G", "H", "I", "J")
my_names <- c("Mary", "Joe", "John", "Steve", "Bob", "Linda", "Emily", "Kevin", "Michael", "Tom")
my_number <- as.character(1:10)
my_df <- data.frame(my_letters, my_names, my_number)
letter_choices <- as.character(unique(my_df$my_letters))


ui <- fluidPage(
  sidebarPanel(
    selectInput("num_selected", label = "Select Letters", choices = letter_choices, selected = "", multiple = TRUE, selectize = TRUE)    
  ),
  mainPanel(
    uiOutput("txt")
  )
)

server<-function(input,output,session){

  output$txt <- renderUI({
    amt <- length(input$num_selected)
    if(!amt) return(NULL)
    tagList(lapply(1:amt, function(nr){
        tagList(
          textOutput(paste0("Name", nr)),
          textOutput(paste0("Number", nr))
        )
      })
    )
  })

    # if selected value = 0 dont create a condPanel,...
  observe({
    amt <- length(input$num_selected)
    if(!amt) return(NULL)
    lapply(1:amt, function(nr){
        local({
          idx <- which(input$num_selected[nr] == my_df$my_letters)
          output[[paste0("Name", nr)]] <- renderText({ as.character(my_df$my_names[idx]) })
          output[[paste0("Number", nr)]] <- renderText({ as.character(my_df$my_number[idx]) })
        })
    }) 
  })

}

shinyApp(ui=ui, server=server)
Sign up to request clarification or add additional context in comments.

8 Comments

I additionally have reactive variables that filters my dataframe that filter the data based on like info (my actual data isn't as tidy as the mock data I created in this post). Those reactive variables are currently named filteredData1, filteredData2 etc. How would I define those iteratively? I've tried it like so paste0("filteredData", idx) <- reactive({ ... Any idea why this wouldn't work and a solution that would work?
When I attempt the code in the comment above, the error in the console references the line where I attempt it with the error Error in <-: target of assignment expands to non-language object
ok, but that still requires an assignment to a variable name, which I have multiple (filteredData1 and filteredData2 will both be used at the same time to display different data sets on the same shiny page) so how would you go about assigning that iteretively when paste0 does not work for variable assignments.
So if I understand correctly, amt is a numeric representing how many inputs the user has selected, and idx is the index that the function is currently working on? So if amt = 4, idx will equal 1, 2, 3, and 4? I am asking because I got my textOutputs working, but am having some trouble deploying your solution with my plots so I am trying to understand the logic of the code better.
I feel like idx is more than just a numbered index and I am not understanding that
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.