daniell
daniell

Reputation: 179

Warning: Error in FUN: object '' not found in R shiny

I want to build a reactive plot in R shiny. The plot should count the number of rows with variable creadate having a certain value. The data that will feed in will be filtered by the selection of employeeName, typeName, and date. I write the following:

library(shiny)
library(shinyWidgets)
library(tidyverse)

data <- tibble(employee= c("John", "Mary", "Lisa"), type = c("AA", "AB", "AB"), 
               creadate = as.Date(c("2018-11-29", "2018-11-22", "2018-11-220")))

employee <- sort(unique(data$employee))
type <- sort(unique(data$type))

ui <- fluidPage(
  fluidRow(
    column(4,
           selectInput("employeeName", "Name of employee", employee, multiple = TRUE),
           selectInput("typeName", "Type", type, multiple = TRUE),
           dateRangeInput("date", "Date", start  = "2020-01-01")
    ),
    column(8,
           plotOutput("policyPlot")
    )
  )
)

server <- function(input, output, session) {
  
  #create a reactive object with a NULL starting value
  listofrows <- reactiveValues(data = NULL)
  
  #observe the changes in inputs and update the reactive object 
  observeEvent(c(input$employee, input$typeName, input$date), {
    
    listofrows$data <- subset(data, employee == input$employee &
                                type == input$typeName & 
                                creadate >= input$date[1] & creadate <= input$date[2]) 
    
  }, ignoreInit = T, ignoreNULL = TRUE)
  
  output$policyPlot <- renderPlot(
    ggplot(listofrows$data) +
      stat_count(aes(creadate))
  )
  
}

shinyApp(ui, server)

However, I get the following error:

Warning: Error in FUN: object 'creadate' not found
  183: FUN
  182: lapply
  181: scales_add_defaults
  180: f
  179: l$compute_aesthetics
  178: f
  177: by_layer
  176: ggplot_build.ggplot
  174: print.ggplot
  166: func
  164: f
  163: Reduce
  154: do
  153: hybrid_chain
  125: drawPlot
  111: <reactive:plotObj>
   95: drawReactive
   82: origRenderFunc
   81: output$policyPlot
    1: runApp

Does someone know why this happens? creadate variable should be in listofrows$data.

Upvotes: 0

Views: 1292

Answers (1)

gdevaux
gdevaux

Reputation: 2505

You get this error because at the beginning, listofrows$data is NULL, because all inputs are NULL.

Just add req(listofrows$data) before plotting to handle missing inputs. Source https://shiny.rstudio.com/articles/req.html

  output$policyPlot <- renderPlot({
    req(listofrows$data)
    ggplot(listofrows$data) +
      stat_count(aes(creadate))
  })

EDIT : for your other errors, I made other modifications :

  • change input$employee by input$employeeName
  • change == by %in% in subset to keep all the chosen inputs
  • add req() statements in observEvent
    library(shiny)
    library(shinyWidgets)
    library(tidyverse)
    library(ggplot2)
    
    
    data <- tibble(employee= c("John", "Mary", "Lisa"), type = c("AA", "AB", "AB"), 
                   creadate = as.Date(c("2020-11-29", "2020-11-22", "2020-11-22")))
    
    employee <- sort(unique(data$employee))
    type <- sort(unique(data$type))
    
    ui <- fluidPage(
      fluidRow(
        column(4,
               selectInput("employee", "Name of employee", employee, multiple = TRUE),
               selectInput("typeName", "Type", type, multiple = TRUE),
               dateRangeInput("date", "Date", start  = "2020-01-01")
        ),
        column(8,
               plotOutput("policyPlot")
        )
      )
    )
    
    server <- function(input, output, session) {
      
      #create a reactive object with a NULL starting value
      listofrows <- reactiveValues(data = NULL)
      
      #observe the changes in inputs and update the reactive object 
      observeEvent(c(input$employee, input$typeName, input$date), {
        req(input$employee)
        req(input$typeName)
        req(input$date)
        listofrows$data <- subset(data, employee %in% input$employee &
                                    type %in% input$typeName & 
                                    creadate >= input$date[1] & creadate <= input$date[2]) 
        
      }, ignoreInit = T, ignoreNULL = TRUE)
      
      
      output$policyPlot <- renderPlot({
        req(listofrows$data)
        ggplot(listofrows$data) +
          stat_count(aes(creadate))
      })
      
    }
    
    shinyApp(ui, server)

Upvotes: 3

Related Questions