Search code examples
rggplot2dplyrshinyreactive-programming

Issue with filter() when inputting .csv file in Shiny R


I am having issues importing data from a .csv file input, and then filtering the date from that file. If I hardcode the file using data_input <- read.csv('Testy.csv'), the app runs smoothly. However, if I use fileInput() to select the same Testy.csv file, I get the following error message in my console:

Error: no applicable method for 'filter' applied to an object of class "c('reactiveExpr', 'reactive', 'function')".
library(shiny)
library(ggplot2)
library(dplyr)

ui <- fluidPage(
  fileInput("csv_input", "Select file", accept = ".csv"),
  dateRangeInput('date_range', 'Pick Range',
                 start = '2024-06-11',
                 end = '2024-06-13',
                 min = '2024-06-11',
                 max = '2024-06-15'),
  actionButton('run', 'Run'),
  plotOutput('plot')
)

server <- function(input,output){
  
  data_input <- reactive({
    req(input$csv_input)
    df(fread(input$csv_input$datapath))
  })
  
  data_input <- reactive({data_input |> mutate(y = lubridate::mdy(y))
  })
  
  data_filtered <- eventReactive(input$run,{
                                 filter(data_input, as.Date(y) >= as.Date(input$date_range[1]) & as.Date(y) <= as.Date(input$date_range[2]))
  })

  
  output$plot <- renderPlot(
    ggplot(data_filtered(), aes(x = y, y = time))+geom_point()
  )
}

shinyApp(ui = ui, server = server)

I included the data from Testy.csv below using dput() but was unable to minimize the need to create a .csv file since that is what's causing the problem.

structure(list(length = c(0L, 1L, 2L, 3L, 4L, 5L, 7L, 8L, 9L, 
10L), sec = c("00:00.0", "00:01.0", "00:02.0", "00:03.0", "00:04.0", 
"00:05.0", "00:06.0", "00:07.0", "00:08.0", "00:09.0"), time = c(30L, 
40L, 50L, 60L, 70L, 80L, 90L, 100L, 110L, 120L), colors = c(5L, 
5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L), y = c("6/11/2024", "6/12/2024", 
"6/13/2024", "6/14/2024", "6/15/2024", "6/16/2024", "6/17/2024", 
"6/18/2024", "6/19/2024", "6/20/2024")), class = "data.frame", row.names = c(NA, 
-10L))

Solution

  • I have corrected your code and the app now loads data and graph as expected:

    library(shiny)
    library(ggplot2)
    library(dplyr)
    
    ui <- fluidPage(
      fileInput("csv_input", "Select file", accept = ".csv"),
      dateRangeInput('date_range', 'Pick Range',
                     start = '2024-06-11',
                     end = '2024-06-13',
                     min = '2024-06-11',
                     max = '2024-06-15'),
      actionButton('run', 'Run'),
      plotOutput('plot')
    )
    
    server <- function(input,output){
      
      data_input <- reactive({
        req(input$csv_input)
        df <- read.csv(input$csv_input$datapath)
        return(df)
      })
      
      data_input_0 <- reactive({data_input() |> mutate(y = lubridate::mdy(y))
      })
      
      data_filtered <- eventReactive(input$run,{
        filter(data_input_0(), as.Date(y) >= as.Date(input$date_range[1]) & as.Date(y) <= as.Date(input$date_range[2]))
      })
      
      
      output$plot <- renderPlot(
        ggplot(data_filtered(), aes(x = y, y = time))+geom_point()
      )
    }
    
    shinyApp(ui = ui, server = server)
    

    First of all, you had a couple of typos in your code, especially with regard to data_input(). You missed the bracket in the filter() function and the reactive function that calls mutate().

    Secondly, I replaced fread() with basic read.csv() in the file input logic, and then returned the uploaded file.

    Lastly, I replaced data_input with data_input_0 in the code

    data_input_0 <- reactive({data_input() |> mutate(y = lubridate::mdy(y))})
      
    

    Failure to do so was creating another error about nearing CStack limit.