Siemkowski Siemkowski - 2 months ago 24
R Question

if statement get rid of: Error in if: argument is of length zero

The idea

Depending on

selectizeInput()
input I want to display one row of data from a data frame. However, some variables are only to be displayed if their value is not
FALSE
.
selectizeInput()
includes a placeholder prompt, which is highly desirable.

The problem

The code I developed actually works but until any option is selected displays


Error in if: argument is of length zero


inside the app, which is highly undesirable.

Example code

library("shiny")

# simulate data
data <- data.frame(
name = c("Adam", "Debbie", "Lancelot", "Dracula"),
age = c(21, 48, 72, 1023),
coward = c("yes, a coward", "just a little bit", FALSE, "too old to be a coward")
)

ui <- fluidPage(
# selectize
selectizeInput(
inputId = "input",
label = NULL,
choices = c("..." = "", as.character(data[, "name"])),
selected = NULL,
multiple = FALSE
),
# show output
uiOutput(outputId = "output")
)

server <- function(input, output, session){
output$output <- renderUI({
div(
# show name
data[which(input$input == data[, "name"]), "name"], br(),
data[which(input$input == data[, "name"]), "age"], br(),
# if "coward" is not FALSE than show its value
if(data[which(input$input == data[, "name"]), "coward"] != FALSE){
data[which(input$input == data[, "name"]), "coward"]
}
)
})
}

shinyApp(ui, server)


Attempted solutions

Tried wrapping
if()
statement in
suppressWarnings()
or
suppressMessages()
. Does not change anything. Also tried putting
!is.null(input$input) &&
inside
if()
condition but it just changes the initial error to


Error: missing value where TRUE/FALSE needed


The question

How to write the condition so that
shiny
would not return an error before selecting an option in
selectizeInput()
?

Any other, more general hack to force
shiny
not to display error messages inside the app?

I feel I`m missing something obvious here...

Answer

The answer including browser() function was indeed helpful for locating the source of the problem but the real solution is to use req() or a combination of validate() and need() functions. See respective help() pages to learn how to use them.

In short what these functions do is to check whether the argument given has been specified. In reference to the example code the solution could look like this:

server <- function(input, output, session){
  output$output <- renderUI({
    # check if input$input is specified
    # if not stop executing the rest of this code block
    req(input$input)
    div(
      # show name
      data[which(input$input == data[, "name"]), "name"], br(),
      data[which(input$input == data[, "name"]), "age"], br(),
      # if "coward" is not FALSE than show its value
      if(data[which(input$input == data[, "name"]), "coward"] != FALSE){
        data[which(input$input == data[, "name"]), "coward"]
      }
    )
  })
}