R Shiny中使用renderUI后出现「Error in :: argument of length 0」错误的原因
错误诱因
你遇到的报错是Shiny服务端渲染UI时的典型时序问题:
- 未使用
renderUI的版本中,sliderInput('samples')随UI初始化直接生成,应用启动时input$samples就有默认值10,renderPlot执行时不会读取空值,因此没有报错。 - 使用
renderUI的版本中,UI初始加载时只有占位的uiOutput("panel"),sliderInput要等服务端的renderUI执行完成后才会渲染到前端,对应的input$samples才会被赋值。应用启动瞬间renderPlot会先于renderUI执行一次,此时input$samples为NULL,执行1:input$samples时就会抛出「argument of length 0」的错误;等renderUI渲染完成、input$samples有值后,renderPlot会被触发重跑,所以后续应用功能完全正常。
修复方案
只需要在renderPlot读取input$samples前加req(input$samples)校验即可,该函数会在输入值无效时主动终止后续代码执行,不会抛出错误,修改后完整代码如下:
library(shiny) library(tidyverse) library(ggplot2) ui <- fluidPage( sidebarLayout(sidebarPanel(uiOutput("panel")), mainPanel(plotOutput("plot")), )) server <- function(input, output, session) { output$panel <- renderUI({ tagList( sliderInput('samples','Number of samples (X):',min=2,max=10,value=10), actionButton("add", "Add scenario") ) }) numScenarios <- reactiveValues(numS=1) observeEvent(input$add, {showModal(modalDialog(footer = modalButton("Close"))) numScenarios$numS <- (numScenarios$numS+1) }) output$plot <- renderPlot({ # 新增该行校验输入值有效性 req(input$samples) v <- tibble() for (i in 1: numScenarios$numS){ results=tibble(Scenario=i,X=1:input$samples,Y=runif(input$samples)) v <- bind_rows(v, results) } v %>% ggplot() + geom_line(aes(x=X, y=Y, colour=as.factor(Scenario))) }) } shinyApp(ui, server)
内容的提问来源于stack exchange,提问作者Curious Jorge - user9788072
相关产品推荐
相关产品推荐

