Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
684 views
in Technique[技术] by (71.8m points)

r - How to get a warning on "shiny app will not work if the same output is used twice"

This is an old Shiny issue: shiny app will not work if the same "output" is used two times in Ui.R

A simple example :

library(shiny)
## app.R ##
server <- function(input, output) {
  output$distPlot <- renderPlot({
    hist(rnorm(input$obs), col = 'darkgray', border = 'white')
  })
}

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      sliderInput("obs", "Number of observations:", min = 10, max = 500, value = 100)
    ),
    mainPanel(plotOutput("distPlot")
              # If the next line is commented out, histogram appears correctly
              ,plotOutput("distPlot")
              )
  )
)

shinyApp(ui = ui, server = server)

This doesn't work because :

Shiny doesn't support multiple outputs with the same name. This code would generate HTML where two elements have the same ID, which is invalid HTML. See this or this.

The result looks fine, but isn't what is expected (no histogram shown) :
enter image description here

The ShinyApp seems to be working normally :

Listening on http ://127.0.0.1:7081

Although I know this issue, I have already been tricked a few times in complex UIs, and I was wondering if there was a way to output an automatic warning in the console on this?
For example :

Warning message: Output 'distPlot' is used twice in UI - this is not supported and might lead to unexpected results

Thanks for sharing your solutions on this issue!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Under the assumption that most Shiny UI outputs follow this pattern :

outputTypeOutput("outputname")

I wrote the checkShinyOutput function which can be called before UI definition in UI script :

checkShinyOutput <- function(){
  tryCatch({
      parsed <- getParseData(parse(file = rstudioapi::getSourceEditorContext()$path))
      shinyOutput <- parsed[parsed$token=='SYMBOL_FUNCTION_CALL'& grepl("^[a-z]+[A-z]+Output$",parsed$text),]
      shinyOutput <- merge(shinyOutput,parsed,by='line1')
      shinyOutput <- shinyOutput[shinyOutput$token.y == "STR_CONST",]
      warn <- table(shinyOutput$text.y)
      warn <- warn[warn>=2]
      warnname <- names(warn)
      if (length(warn>1)) {
       warning(mapply(function(warn,nb){paste("Output",warn,"is used",nb,"times")},warnname,warn))
      }
    },
    error = function(){},
    warning = function(cond) {
      message("Shiny UI : check following warnings to avoid unexpected UI behaviour")
      message(cond)
    } 
  )
} 

This appears in Console when the app is run from RStudio :

> runApp('test')
Shiny UI : check following warnings to avoid unexpected UI behaviour
Output "distPlot" is used 2 times
Listening on http://127.0.0.1:7414

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...