我正在尝试基于多个预定义列表动态生成用户输入,我的目标是通过允许它符合预定义的数据结构来简化代码可维护性。下面是我所遇到的问题的简化版本的代码和解释:
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)
下面描述的所有用户输入都是根据上面闪亮应用中UI之前定义的参数,模型和分发列表生成的。
因此,用户首先从两个下拉菜单中选择一般模型,然后选择特定模型。然后,根据特定模型的不同,“输入”选项卡将填充与所选模型的参数对应的选项卡。然后,用户可以从选项卡内的下拉菜单中选择每个参数的分布。
之后,用户应该能够填充与分发参数对应的一系列数字输入。我试图动态生成那些数字输入,但我一直得到:
Error: attempt to select less than one element in get1index
我的尝试代码位于应用程序的末尾并被注释掉,取消注释以重现错误。