R shiny: How to get an reactive data frame updated each time pressing an actionButton without creating a new reactive data frame?

Lawrence Lee picture Lawrence Lee · Apr 18, 2015 · Viewed 30.7k times · Source

My shiny app allows user to upload a csv by using fileInput and stored as an reactive object df_data. I then created a numericInput for user to enter a row number to delete from the data frame. However, I got an error about evaluation nested too deeply: infinite recursion / options(expressions=)?.

Below is my code for ui.R.

shinyUI(fluidPage(
  titlePanel("amend data frame"),

  mainPanel(
    fileInput("file", "Upload file"),

    numericInput("Delete", "Delete row:", 1, step = 1),
    actionButton("Go", "Delete!"),

    tableOutput("df_data")
  )
))

And below is my code for server.R.

shinyServer(function(input, output) {
  df_data <- reactive({
    read.csv(input$file$datapath)
  })

  df_data <- eventReactive(
    input$Go,
    df_data()[-input$Delete,]
  )

  output$df_data <- renderTable(df_data())
})

I have solved the problem by assigning the subsetted data frame to a new reactive data frame called, say, df_data2. But I want to make the user able to keep deleting different rows by inputting values in Delete row and press the Go button. Then this solution will not work as I will have to assign df_data3, df_data4 ... and I couldn't predict in advance how many times the user will press the Go button.

I am a new user to shiny for about 2 weeks and I have been searching for solutions about this for a week. Is there anyone who can help me? A million thanks !!

Answer

DeanAttali picture DeanAttali · May 28, 2015

Below is a working solution. I created a reactiveValues to store the dataframe. When a file is chosen, the dataframe gets populated. When the delete button is pressed, that same dataframe gets a row deleted. The table always outputs whatever that dataframe object is holding. I hope this code can be a good learning material

runApp(shinyApp(
ui=(fluidPage(
  titlePanel("amend data frame"),

  mainPanel(
    fileInput("file", "Upload file"),

    numericInput("Delete", "Delete row:", 1, step = 1),
    actionButton("Go", "Delete!"),

    tableOutput("df_data_out")
  )
)),
server = (function(input, output) {
  values <- reactiveValues(df_data = NULL)

  observeEvent(input$file, {
    values$df_data <- read.csv(input$file$datapath)
  })

  observeEvent(input$Go, {
    temp <- values$df_data[-input$Delete, ]
    values$df_data <- temp

  })

  output$df_data_out <- renderTable(values$df_data)
})))