闪亮:使用列表动态生成数字输入时出错

时间:2017-07-04 12:38:09

标签: r input shiny numeric-input

我正在尝试基于多个预定义列表动态生成用户输入,我的目标是通过允许它符合预定义的数据结构来简化代码可维护性。下面是我所遇到的问题的简化版本的代码和解释:

library(shiny)

distributions <- list(
  "Distribution 1" = list("Distribution 1 Parameter 1" = list("Lower" = 0, "Upper" = Inf, "Default" = 1))
)

models <- list(
  "General Model 1" = list("Specific Model 1")
)

parameters <- list(
  "Specific Model 1" = list("Specific Model 1 Parameter 1")
)

ui <- fluidPage(
  # Model selection 
  fluidRow(
    selectInput("generalModel", "General Model", names(models)),
    selectInput("specificModel", "Specific Model", models[[1]]),
    tabsetPanel(
      # Tab for inputs
      tabPanel(
        title = "Inputs",
        uiOutput("inputsTabs")
      )
    )
  )
)  

server <- function(input, output, session) {
  # Handling model selection
  observe({
    updateSelectInput(session, "specificModel", choices = models[[input$generalModel]])
  })

  # Displaying inputs for a specific model in tabs
  output$inputsTabs <- renderUI({
    nTabs = length(parameters[[input$specificModel]])
    tabs = lapply(seq_len(nTabs), function(i) {
      tabPanel(
        paste0(parameters[[input$specificModel]][[i]]),
        uiOutput(paste0(input$specificModel, "Input", parameters[[input$specificModel]][[i]]))
      )
    })
    do.call(tabsetPanel, tabs)
  })

  # Creating inputs for each specific parameter
  observe(
    lapply(seq_len(length(parameters[[input$specificModel]])), function(i) {
      output[[paste0(input$specificModel, "Input", parameters[[input$specificModel]][[i]])]] <- renderUI({
        distribution <- paste0(input$specificModel, "Input", parameters[[input$specificModel]][[i]], "Distribution")
        selectInput(inputId = distribution, label = "Distribution",  choices = names(distributions))
        uiOutput(paste0(distribution, "Parameters"))
      })
    }), 
    priority = 100
  )

  # Creating inputs for each specific parameter
  observe(
    lapply(seq_len(length(parameters[[input$specificModel]])), function(i) {
      distribution <- paste0(input$specificModel, "Input", parameters[[input$specificModel]][[i]], "Distribution")
      output[[paste0(distribution, "Parameters")]] <- renderUI({
        nNumericInputs = length(distributions[[input[[distribution]]]])
        numericInputs = lapply(seq_len(nNumericInputs), function(i) {
          numericInput(
            inputId = paste0(distribution, input[[input[[distribution]]]], distributions[[input[[distribution]]]][[i]]),
            label = paste0(distributions[[input[[distribution]]]][[i]]),
            value = distributions[[input[[distribution]]]][[i]][[3]],
            max = distributions[[input[[distribution]]]][[i]][[2]],
            min = distributions[[input[[distribution]]]][[i]][[1]]
          )
        })
        do.call(wellPanel, numericInputs)
      })
    }),
    priority = 50
  )

}

shinyApp(ui = ui, server = server)

Image of the app

下面描述的所有用户输入都是根据上面闪亮应用中UI之前定义的参数,模型和分发列表生成的。

因此,用户首先从两个下拉菜单中选择一般模型,然后选择特定模型。然后,根据特定模型的不同,“输入”选项卡将填充与所选模型的参数对应的选项卡。然后,用户可以从选项卡内的下拉菜单中选择每个参数的分布。

之后,用户应该能够填充与分发参数对应的一系列数字输入。我试图动态生成那些数字输入,但我一直得到:

Error: attempt to select less than one element in get1index

我的尝试代码位于应用程序的末尾并被注释掉,取消注释以重现错误。

0 个答案:

没有答案