doublestufcoreo
doublestufcoreo

Reputation: 23

Using reactiveFileReader in Shiny app to update a dataframe upon change to underlying CSV

I'm working on a complex (for me) Shiny app ~2500 lines of code. The basic structure is as follows, though I can't necessarily share a reproducible example since most of the information is confidential.

Right now, I am using df1 <- read.csv() etc to read in several CSV files as dataframes. I want to use reactiveFileReader() to make it such that the dataframes automatically update when the source CSV file is modified. I think my problem may be related to the fact that I am not doing this in a reactive context, but there is a reason for this. I am using the dataframes df1 etc to perform many calculations and to create new variables throughout the app (UI and server sections).

It also might be important to note that I am doing these file imports in the UI part of the Shiny app, since I need to rely on the factor levels of these dataframes to populate drop down selectInput in my UI. This might not be necessary.

Here is what I have tried (although I am pretty lost):

reader <- reactiveFileReader(intervalMillis = 1000, filePath = 
"Data_Record.csv", readFunc = read.csv)

  data_record <- reactive({
    data_df <- reader()
    return(data_df)
  })

What I was expecting was for data_record to be a dataframe containing the information from the CSV, but it ends up being a "reactive expression". When I try to perform operations on data_record, like subsetting, I receive errors since that variable is not a dataframe.

Is there any way for me to update these dataframes upon modification to the underlying CSV outside of a reactive context? Even a scheduled update like every 10 seconds or so would work as well. My ultimate goal are dataframes that update when a CSV is modified, but scheduled updates are fine as well.

Thanks in advance for all the help and I apologize for not being able to supply a reproducible example! I will try to add more information as needed.

Upvotes: 2

Views: 4263

Answers (1)

Paul Campbell
Paul Campbell

Reputation: 876

So if you want the data to be reactive, it has to be imported in the server section of the app as a 'reactive'. In shiny, 'reactives' become functions so to do anything with them you have to reference them their name followed by parenthesis inside a reactive function (reactive, observe, render etc).

For example, with your code above, reader becomes a reactive data frame. You can perform normal data manipulation on reader if you follow the rules of reactives outlined above.

# server.R

reader <- reactiveFileReader(intervalMillis = 1000, filePath = 
"Data_Record.csv", readFunc = read.csv)

filtered_reader_df <- reactive({
  reader() %>% filter(x > 100)
})

Where filtered_reader_df becomes a reactive filtered version of the reactive csv file. Again, to use filtered_reader_df in subsequent reactive function it must be referenced as filtered_reader_df() as it is a reactive function itself.

Finally, you can still use the reactive csv file to populate UI elements with the updateSelectInput() function inside an observer in the server. For example:

ui <- fluidPage(
  selectInput("mySelectInput", "Select")
)

server <- function(input, output, session) {

  reader <- reactiveFileReader(intervalMillis = 1000, filePath = 
                                 "Data_Record.csv", readFunc = read.csv)

  observe({
    select_input_choices <- unique(reader()$factor_column)

    updateSelectInput(session, inputId = "mySelectInput", choices = select_input_choices)
  })

}

The code above will update the choices of the select input every time the reader() data frame changes with the reactiveFileReader where unique(reader()$factor_column) are the reactive unique values of the factor column you want to populate the input with.

Upvotes: 3

Related Questions