title: How to edit a table using DT and Shiny from an uploaded file?
body: <p>I am relying on the code chunk found <a href="https://github.com/rstudio/DT/issues/28#issuecomment-236293247" rel="nofollow noreferrer">here</a> to create a Shiny app to upload a table, edit the table, then download the table. I have managed to edit a table that is already loaded in memory (iris) but <strong>how do I edit a table that is to be uploaded in Shiny?</strong>.</p>
  
  <p>I have tried the code in the link above and verified that it works. I have also tried the code below and this works too. What I have not been able to achieve is to convert the data frame <code>x</code> into a reactive object that is assigned to an uploaded file, and edit all the references to <code>x</code> accordingly.</p>
  
  <pre><code># This code works, but lacks a fileinput object 
  # and needs to be amended for a reactive dataframe...
  library(shiny)
  library(DT)
  shinyApp(
    ui = fluidPage(
      fluidRow(
      # ~~ add fileInput("file1", "Choose file") here ~~
      downloadButton("download")
      ),
      fluidRow(
      DT::dataTableOutput('x1')
      )
    ),
    server = function(input, output, session) {
      # Do I make x reactive?
      x = iris
      x$Date = Sys.time() + seq_len(nrow(x))
      output$x1 = DT::renderDataTable(x, selection = 'none', rownames = FALSE, edit = TRUE)
  
      proxy = dataTableProxy('x1')
  
      observeEvent(input$x1_cell_edit, {
        info = input$x1_cell_edit
        str(info)
        i = info$row
        j = info$col + 1
        v = info$value
        x[i, j] &lt;&lt;- DT:::coerceValue(v, x[i, j])
        replaceData(proxy, x, resetPaging = FALSE, rownames = FALSE)
      })
  
      output$download &lt;- downloadHandler("example.csv", 
                                         content = function(file){
                                           write.csv(x, file)
                                         },
                                         contentType = "text/csv")
  
      }
  )
  </code></pre>
  
  <p>Previous attempts at this have thrown errors, mostly to do with operations not being allowed without an active reactive context.</p>
  
  <p>The code below shows what I want to achieve, but throws an error: 
  <em>"argument "expr" is missing, with no default"</em></p>
  
  <pre><code>library(shiny)
  library(DT)
  shinyApp(
    ui = fluidPage(
      fluidRow(
        fileInput("upload", "Choose CSV File",
                  multiple = FALSE,
                  accept = c("text/csv",
                             "text/comma-separated-values,text/plain",
                             ".csv")),
      downloadButton("download")
      ),
      fluidRow(
      DT::dataTableOutput('x1')
      )
    ),
    server = function(input, output, session) {
      #x = iris
  
      # In this edited example x is now a reactive expression, dependent on input$upload
      x &lt;- eventReactive({
  
  
        # input$file1 will be NULL initially. After the user selects
        # and uploads a file, head of that data file by default,
        # or all rows if selected, will be shown.
  
       req(input$upload)
  
        # when reading semicolon separated files,
        # having a comma separator causes `read.csv` to error
        tryCatch(
          {
            x &lt;- read.csv(input$upload$datapath,
                           header = TRUE,
                           sep = ",",
                           stringsAsFactors = TRUE,
                           row.names = NULL)
  
          },
          error = function(e) {
            # return a safeError if a parsing error occurs
            stop(safeError(e))
           }
        )
      })
  
      #x$Date = Sys.time() + seq_len(nrow(x))
      output$x1 = DT::renderDataTable(x(), selection = 'none', rownames = FALSE, edit = TRUE)
  
      proxy = dataTableProxy('x1')
  
      observeEvent(input$x1_cell_edit, {
        info = input$x1_cell_edit
        str(info)
        i = info$row
        j = info$col + 1
        v = info$value
        x()[[i, j]] &lt;&lt;- DT:::coerceValue(v, x()[[i, j]])
        newdf &lt;- x()
        replaceData(proxy, newdf, resetPaging = FALSE, rownames = FALSE)
      })
  
      output$download &lt;- downloadHandler("example.csv", 
                                         content = function(file){
                                           write.csv(x(), file)
                                         },
                                         contentType = "text/csv")
  
      }
  )
  </code></pre>