我正在尝试根据
R shiny app
中给出的用户输入计算几个值。一些用户输入取决于其他一些输入设置(因此 ui 是交互式的,滑块范围取决于另一个值;这是使用 renderUI
解决的)。到目前为止效果很好。在服务器端,我想计算反应函数中的结果值。反应函数返回一个数组/数据帧,该数组/数据帧由取决于滑块输入的这些值填充。整个脚本运行良好并提供了正确的输出,但我收到了一些错误/警告消息,我不知道如何处理它们以及为什么会引发这些消息(Warning: Error in <-: number of items to replace is not a multiple of replacement length
)。
这里是重现错误消息的示例:
library(shiny)
ui <- fluidPage(
titlePanel("Test"),
sidebarLayout(position="left",
sidebarPanel(selectInput(inputId = "Category", label="Category to choose",
choices = list("A" = "A", "B" = "B"),
selected = "A"),
sliderInput(inputId = "sl_1",
label = "Test slider",
value = 3, min = 1, max = 5),
uiOutput("slider_test")),
mainPanel(tableOutput("outtable"),
tableOutput("outtext"))))
server <- function(input, output){
# Dynamic slider ranges depending on turbine type
slider_param <- reactive({
par_ls <- list()
if(input$Category=="A"){
par_ls$range <- 20
par_ls$max <- 1000
}
if(input$Category=="B"){
par_ls$range <- 10
par_ls$max <- 500
}
return(par_ls)
})
output$slider_test <- renderUI({
sliderInput(inputId = "sl_2",
label = "Test slider",
value = slider_param()$range, min = 1, max = slider_param()$max)})
## Calculate parameters on the fly an store in data.frame() for display
output_reactive <- reactive({
results_array <- array(data = NA,
dim = c(1,2),
dimnames = list(c("row1"),
c("colA","colB")))
results_array["row1","colA"] <- input$sl_2
results_array["row1","colB"] <- input$sl_1*input$sl_2
return(as.data.frame(results_array))
})
output$outtext <- renderText({input$sl_2})
output$outtable <- renderTable({
output_reactive()})
}
shinyApp(ui = ui, server = server)
我认为此错误可能是由滑块
input$sl_2
的输出值的生成/处理方式(即按顺序)引起的。由于 input$sl_2
在设置 input$Category
(即条件滑块)后更新,input$sl_2
一开始可能为空。例如,这会产生相同类型的错误:
results_array <- array(data = NA,
dim = c(1,2),
dimnames = list(c("row1"),
c("colA","colB")))
sl_2 <- c()
results_array["row1","colA"] <-sl_2
解决方案: 我通过将
req()
插入 renderTable()
找到了解决方案。 req()
仅当 input$sl_2 不为空时才会告诉shiny渲染该表[https://stackoverflow.com/a/43619933/1035346]
output$outtable <- renderTable({
req(input$sl_2)
output_reactive()})