1

I am trying to set a default (or fallback) value for numericInput() in my shiny app to prevent NAs.

I am aware that the NA can be dealt with later in the server.r, but was wondering if there is a more elegant way of replacing the value within the input whenever a user deletes it in the ui.

fschier
  • 180
  • 10

2 Answers2

1

The best way is to use the validate package with need() (see this SO thread), but here is something simpler and closer to what you are asking for:

library(shiny)

ui <- fluidPage(
  numericInput("obs", "Observations:", 10, min = 1, max = 100),
  verbatimTextOutput("value")
)

server <- function(input, session, output) {
  
  dafault_val <- 0
  
  observe({
    if (!is.numeric(input$obs)) {
      updateNumericInput(session, "obs", value = dafault_val)
    }
  })
  
  output$value <- renderText({ input$obs })
}

shinyApp(ui, server)
Claudiu Papasteri
  • 2,469
  • 1
  • 17
  • 30
  • Thanks, this does work quite well indeed. Would multiple of these observe calls have a substantial effect on the performance of an shiny app? – fschier Jan 18 '22 at 16:00
  • I usually use quite a bunch of them and they don't seem to impact performance that much. Setting rules through `validate` or `shinyvalidate` wouldn't probably be (much) more efficient for simple stuff like this. I am not a `shiny` expert, so can't really provide any guarantees here. – Claudiu Papasteri Jan 18 '22 at 16:06
  • In my case I would have about 20 Inputs where I would need to create an observe({ }). – fschier Jan 18 '22 at 16:14
  • You could try benchmarking the solutions (https://mastering-shiny.org/performance.html), but I would not expect this to be the bottleneck of an app as people are inputting values sequentially anyway. Overoptimizing already fast methods is often worse than ignoring performance issues. – Claudiu Papasteri Jan 18 '22 at 16:21
1

I'd recommend using library(shinyvalidate), which is RStudios "official" way to solve this:

library(shiny)
library(shinyvalidate)

ui <- fluidPage(
  numericInput(
    inputId = "myNumber",
    label = "My number",
    value = 0,
    min = 0,
    max = 10
  ),
  textOutput("myText")
)

server <- function(input, output, session) {
  iv <- InputValidator$new()
  iv$add_rule("myNumber", sv_required(message = "Number must be provided"))
  iv$add_rule("myNumber", sv_gte(0))
  iv$add_rule("myNumber", sv_lte(10))
  iv$enable()
  
  output$myText <- renderText({
    req(iv$is_valid())
    input$myNumber
  })
  
}

shinyApp(ui, server)
ismirsehregal
  • 30,045
  • 5
  • 31
  • 78