Reputation: 5
I'm writing a Shiny app that allows users to view and change multiple data frames. Ultimately, I'd like the changes to overwrite values in the original data frames so that they can be used in a calculation. Below is what I have so far. I've figured out how to allow the user to switch between dataframes, change values for the dfs, and "reset" the changes to the original values for df1 and df2. But I'd like to add an observeEvent that overwrites df1 and df2 with user changes.
library(shiny)
library(DT)
df1 <- data.frame(a = c('a','b','c','d','e'),
b = round(rnorm(5, 0,1),2))
df2 <- data.frame(a = c('a','b','c','d','e'),
b = round(rnorm(5, 1,1.5),2))
ui <- fluidPage(
titlePanel("example"),
sidebarLayout(
sidebarPanel(
selectInput(inputId = "df",
label = "Choose a table:",
choices = c("df1",
"df2")),
),
mainPanel(
actionButton("reset", "Reset"),
actionButton("save", "Save Changes"),
DTOutput("df")
)
)
)
server <- function(input, output) {
dfInput <- reactive({
switch(input$df,
"df1" = df1,
"df2" = df2)
})
observeEvent(input$reset, {
output$df <- renderDT(dfInput(), editable = TRUE,
options = list(lengthChange = FALSE))
})
output$df <- renderDT(dfInput(), editable = TRUE,
options = list(lengthChange = FALSE))
}
shinyApp(ui = ui, server = server)
Thanks!
Upvotes: 0
Views: 300
Reputation: 30494
One possible solution is to use observeEvent
and record any edits made in real-time, instead of waiting for user to hit save button. If that approach works for you, then this might be helpful.
Note that you only need one output
instead of two, and that reset
will automatically revert to original data. To do this, you can use reactiveValues
to store your data. In this case, I made a list
of two data frames for df1
and df2
.
Also, to allow for testing with edits in this example, I added stringsAsFactors = FALSE
to your two data.frames when created (so edits not limited to factor levels).
library(shiny)
library(DT)
df1 <- data.frame(a = c('a','b','c','d','e'),
b = round(rnorm(5, 0,1),2),
stringsAsFactors = F)
df2 <- data.frame(a = c('a','b','c','d','e'),
b = round(rnorm(5, 1,1.5),2),
stringsAsFactors = F)
ui <- fluidPage(
titlePanel("example"),
sidebarLayout(
sidebarPanel(
selectInput(inputId = "df",
label = "Choose a table:",
choices = c("df1",
"df2")),
),
mainPanel(
actionButton("reset", "Reset"),
#actionButton("save", "Save Changes"),
DTOutput("df")
)
)
)
server <- function(input, output) {
rv <- reactiveValues(tables = list("df1" = df1, "df2" = df2))
dfInput <- reactive({
rv$tables[[input$df]]
})
observeEvent(input[["df_cell_edit"]], {
cell <- input[["df_cell_edit"]]
rv$tables[[input$df]][cell$row, cell$col] <- cell$value
})
observeEvent(input$reset, {
rv$tables <- list("df1" = df1, "df2" = df2)
})
output$df <- renderDT(dfInput(), editable = TRUE,
options = list(lengthChange = FALSE))
}
shinyApp(ui = ui, server = server)
Upvotes: 0