Search code examples
rshinyreactive

IDEAFilter R package not working under reactive expression


I am trying to upload a file using fileInput() function and use the R package IDEAFilter to filter it and show the filtered data. But it seems that I can not filter a reactive expression using IDEAFilter package. I am not sure if that's true or my code is wrong. Here is my code:

library(shiny)
library(bslib)
library(IDEAFilter)
library(dplyr)

ui <- page_fixed(
    fileInput("file1", "Choose CSV File", accept = ".csv"),
    IDEAFilter_ui("data_filter"),
    verbatimTextOutput("file1_contents"),
    tableOutput("contents"),
    tableOutput("contents1")
)

server <- function(input, output) {
    output$file1_contents <- renderPrint({print(input$file1)})
    
    output$contents <- renderTable({
        file <- input$file1
        req(file)
        ext <- tools::file_ext(file$datapath)
        validate(need(ext == "csv", "Please upload a csv file"))
        a<- read.csv(file$datapath)
        a
    })

    filtered_data<-reactive({
        file <- input$file1
        req(file)
        ext <- tools::file_ext(file$datapath)
        validate(need(ext == "csv", "Please upload a csv file"))
        a<- read.csv(file$datapath)
        IDEAFilter("data_filter", data =a,verbose = FALSE)
    })

    output$contents1 <- renderTable({
        filtered_data()
    })
}

shinyApp(ui, server)

I tried to upload data and filter it using IDEAFilter package. It seems that IDEAFilter package is not working with reactive data. If I use the package with data uploaded from the computer it works, but not with reactive data.


Solution

  • Explanations

    When we are looking at the source of IDEAFilter::IDEAFilter(), typing IDEAFilter::IDEAFilter without parenthesis, we can see that IDEAFilter is a shiny moduleServer():

    IDEAFilter::IDEAFilter
    function (id, data, ..., col_subset = NULL, preselection = NULL, 
        verbose = FALSE) 
    {
        moduleServer(id, function(input, output, session) {
           ns <- session$ns
           ...
           observeEvent(...
           ...etc...
        } end of moduleServer
    } end of function
    

    Therefore we have to use it inside a scope of a data if we want to get the data.

    server <- function(input, output) {
    
      react <- reactiveValues(
        filtered_data_idea =NULL
      )
    
      ...
    
      observeEvent(filtered_data.react(),{
        
        req(filtered_data.react())  
        
        react$filtered_data_idea <- IDEAFilter("data_filter", data = filtered_data.react(), verbose = FALSE)
        
      })
    
      ...
    
      output$contents1 <- renderTable({
        if (shiny::is.reactive(react$filtered_data_idea)) {
          react$filtered_data_idea()
        } else NULL
        
      })
    }
    

    IDEAFilter

    I didn't kown IDEAFilter, thanks :)

    Here is all of the source:

    library(shiny)
    library(bslib)
    library(IDEAFilter)
    library(dplyr)
    
    ui <- page_fixed(
      fileInput("file1", "Choose CSV File", accept = ".csv"),
      IDEAFilter_ui("data_filter"),
      verbatimTextOutput("file1_contents"),
      h3("contents filtered by IDEAFilter"),
      tableOutput("contents1"),
      h3("all the contents"),
      tableOutput("contents")
    )
    
    server <- function(input, output) {
      react <- reactiveValues(
        filtered_data_idea =NULL
      )
      
      output$file1_contents <- renderPrint({print(input$file1)})
      
      filtered_data.react<-reactive({
        file <- input$file1
        req(file)
        ext <- tools::file_ext(file$datapath)
        validate(need(ext == "csv", "Please upload a csv file"))
        a<- read.csv(file$datapath)
        a
        
      })
      
      
      observeEvent(filtered_data.react(),{
        
        req(filtered_data.react())  
        
        react$filtered_data_idea <- IDEAFilter("data_filter", data = filtered_data.react(), verbose = FALSE)
        
      })
      
      
      
      output$contents <- renderTable({
        datas <- filtered_data.react()
        
        if (nrow(datas)) (datas)
        else NULL
        
      })
      
      
      output$contents1 <- renderTable({
        if (shiny::is.reactive(react$filtered_data_idea)) {
          react$filtered_data_idea()
        } else NULL
        
      })
      
      
    }
    
    shinyApp(ui, server)