Сохранить изменения в различных данных в Shiny - PullRequest
0 голосов
/ 04 февраля 2020

Я пишу блестящее приложение, которое позволяет пользователям просматривать и изменять несколько фреймов данных. В конечном счете, я бы хотел, чтобы изменения перезаписывали значения в исходных фреймах данных, чтобы их можно было использовать в расчетах. Ниже то, что я имею до сих пор. Я выяснил, как позволить пользователю переключаться между кадрами данных, изменять значения для dfs и «сбрасывать» изменения в исходные значения для df1 и df2. Но я хотел бы добавить наблюдатель, который перезаписывает df1 и df2 с изменениями пользователя.

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)

Спасибо!

1 Ответ

0 голосов
/ 04 февраля 2020

Одним из возможных решений является использование observeEvent и запись любых изменений, внесенных в режиме реального времени, вместо ожидания нажатия пользователем кнопки «Сохранить». Если этот подход работает для вас, то это может быть полезно.

Обратите внимание, что вам нужен только один output вместо двух, и reset автоматически вернется к исходным данным. Для этого вы можете использовать reactiveValues для хранения ваших данных. В этом случае я сделал list из двух фреймов данных для df1 и df2.

Кроме того, чтобы разрешить тестирование с правками в этом примере, я добавил stringsAsFactors = FALSE к вашим двум данным .frames при создании (поэтому редактирование не ограничивается уровнями фактора).

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)
...