Silentdevildoll
Silentdevildoll

Reputation: 1280

R, Shiny, DT table, replacing data

I'm trying to be able to edit a table through a text input followed by an action button. In addition, I'd like the data to stay changed, so that if I reload the app or enter in new data into the text input, the previous input doesn't revert to the previous value.

I feel like there is likely a simple way to do this, and I see things like this, where we can delete rows: Are table displayed on shiny,read only? But that wouldn't help for when you reload the app. In addition, I don't seem quite able to apply it to just changing a specific cell.

Below I have some simplified code, using mtcars. I added two columns, one giving a Car number, and one for if the car is good. So essentially, I would like to be able to enter 1, then row Car_number 1 will have Good_car column changed to True. Then, when I enter 2, I'd like for both the previous 1 and now 2 to also be True. And finally, next time I reload the app I want them to still be True.

The second data table is just showing that I know the dplyr mutate replace can change specific things in a data table, because when I enter the car number using that it will change Good_car to T for that number, until the input changes then it will revert back.

library(shiny)
library(dplyr)
library(DT)

mtbetter<-mtcars%>%
  mutate(Car_number = c(1:32),
         Good_car = F)


ui <- fluidPage(
      textInput(inputId = "text", label = "Filter Car Number"),
      actionButton("action", "Go!"),
      dataTableOutput(outputId = "table"),
      dataTableOutput(outputId = "table2")
)

server = function(input, output, session){
  mtfinal = reactiveVal(mtbetter)

  output$table<-renderDataTable({
    mtfinal()
    })
  observeEvent(input$action, {mtfinal()%>%
      mutate(Good_car = replace(Good_car, Car_number == input$text, T))})

  output$table2<-renderDataTable({

    mtbetter2<-mtbetter%>%
      mutate(Good_car = replace(Good_car, Car_number == input$text, T))

    mtbetter2

  })

}

shinyApp(ui, server)

I also suspect that Replacedata will do it, but admittedly the documentation still can go over my head sometimes: https://rdrr.io/cran/DT/man/replaceData.html

Upvotes: 2

Views: 2265

Answers (1)

Florian
Florian

Reputation: 25435

You are really close, all you need to do is modify your observeEvent:

observeEvent(input$action, {mtfinal(mtfinal()%>%
     mutate(Good_car = replace(Good_car, Car_number == input$text, T)))})

Why your solution does not do what you want it to do: You call the value of mtfinal() and filter from there. However, you do not write the resulting table back to mtfinal(). So the next time you want to update it, you start again with the initial value for mtfinal(). Since you can set a new value for a reactiveVal called y to x by doing y(x), all we need to do is wrap the entire statement in mtfinal(...). Hope this helps!

Upvotes: 1

Related Questions