RustyStatistician
RustyStatistician

Reputation: 1049

Ammending dynamic input code in R Shiny

So I asked the following, R Shiny Dynamic Input, a couple of days ago and although the answer is correct given the question, I now want to elaborate some more since I am unable to edit the code given to answer my new question. So originally I wanted to be able to ask the user to specify a number, say k, that would then dynamically generate k fields for the user to fill out. Now, the code given assumes that the output is a numeric, however, I want the user to be able to specify a vector of 5 values in each of the 1,...,k fields. Since, after specifying k, the inputs are going to be k vectors of length 5 of numerical values, I want to be able to store these values in a k by 5 matrix. That way I can use those values to conduct data manipulations later. If it helps, here is the code from the original answer:

library(shiny)

ui <- shinyUI(fluidPage(
  titlePanel("Old Faithful Geyser Data"),

  sidebarLayout(
    sidebarPanel(
      numericInput("numInputs", "How many inputs do you want", 4),
      # place to hold dynamic inputs
      uiOutput("inputGroup")
    ),
    # this is just a demo to show the input values
    mainPanel(textOutput("inputValues"))
  )
))

# Define server logic required to draw a histogram
server <- shinyServer(function(input, output) {
  # observe changes in "numInputs", and create corresponding number of inputs
  observeEvent(input$numInputs, {
    output$inputGroup = renderUI({
      input_list <- lapply(1:input$numInputs, function(i) {
        # for each dynamically generated input, give a different name
        inputName <- paste("input", i, sep = "")
        numericInput(inputName, inputName, 1)
      })
      do.call(tagList, input_list)
    })
  })

  # this is just a demo to display all the input values
  output$inputValues <- renderText({
    paste(lapply(1:input$numInputs, function(i) {
      inputName <- paste("input", i, sep = "")
      input[[inputName]]
    }))
  })

})

# Run the application
shinyApp(ui = ui, server = server)

Edit

Here is updated code that still doesn't completely work:

library(shiny)

ui <- shinyUI(fluidPage(
  titlePanel("Old Faithful Geyser Data"),

  sidebarLayout(
    sidebarPanel(
      numericInput("numInputs", "How many inputs do you want", 4),
      # place to hold dynamic inputs
      uiOutput("inputGroup")
    ),
    # this is just a demo to show the input values
    mainPanel(tableOutput("inputValues"))
  )
))

# Define server logic required to draw a histogram
server <- shinyServer(function(input, output) {
  # observe changes in "numInputs", and create corresponding number of inputs
  observeEvent(input$numInputs, {
output$inputValues <- renderTable({
  all <- paste(lapply(1:input$numInputs, function(i) {
    inputName <- paste("input", i, sep = "")
    input[[inputName]]
  }))
  matrix <- as.matrix(all, ncol=5)
  as.data.frame(matrix)
})

  })

  # this is just a demo to display all the input values
  output$inputValues <- renderText({
    paste(lapply(1:input$numInputs, function(i) {
      inputName <- paste("input", i, sep = "")
      input[[inputName]]
    }))
  })

})

# Run the application
shinyApp(ui = ui, server = server)

Upvotes: 0

Views: 854

Answers (1)

Xiongbing Jin
Xiongbing Jin

Reputation: 12087

You only need to make a few changes:

  1. Change mainPanel(textOutput("inputValues")) to mainPanel(tableOutput("inputValues")) (this is not essential, it just shows the values in a table/matrix format so you can see them)
  2. Change numericInput(inputName, inputName, 1) to textInput(inputName, inputName, "1 2 3 4 5")
  3. Change output$inputValues <- renderText({...... to

    output$inputValues <- renderTable({
      all <- paste(lapply(1:input$numInputs, function(i) {
        inputName <- paste("input", i, sep = "")
        input[[inputName]]
      }))
      matrix = as.matrix(read.table(text=all))
      data.frame(matrix)
    })
    

matrix is what you want: a k by 5 matrix.

Note that I did not do any input verification. It is assumed that user will enter 5 numbers in each input separated by spaces. If they do not, output might be either wrong or you'll see an error. You may need to implement some input checking here to ensure that it is 5 numbers and not anything else.

Complete code

library(shiny)

ui <- shinyUI(fluidPage(
  titlePanel("Old Faithful Geyser Data"),

  sidebarLayout(
    sidebarPanel(
      numericInput("numInputs", "How many inputs do you want", 4),
      # place to hold dynamic inputs
      uiOutput("inputGroup")
    ),
    # this is just a demo to show the input values
    mainPanel(tableOutput("inputValues"))
  )
))

# Define server logic required to draw a histogram
server <- shinyServer(function(input, output) {
  # observe changes in "numInputs", and create corresponding number of inputs
  observeEvent(input$numInputs, {
    output$inputGroup = renderUI({
      input_list <- lapply(1:input$numInputs, function(i) {
        # for each dynamically generated input, give a different name
        inputName <- paste("input", i, sep = "")
        textInput(inputName, inputName, "1 2 3 4 5")
      })
      do.call(tagList, input_list)
    })
  })

  # this is just a demo to display all the input values
  output$inputValues <- renderTable({
    all <- paste(lapply(1:input$numInputs, function(i) {
      inputName <- paste("input", i, sep = "")
      input[[inputName]]
    }))
    matrix = as.matrix(read.table(text=all))
    data.frame(matrix)
  })

})

# Run the application
shinyApp(ui = ui, server = server)

Upvotes: 1

Related Questions