使用 DT 的 Shiny 应用程序中反应性 editable table 中的持久数据
Persistent data in reactive editable table in Shiny app using DT
我有一个应用程序,它从 SQL-db 获取数据,然后允许用户编辑它,这应该保存到数据库中。在 repex 中我使用了一个 CSV 文件,但逻辑应该仍然是可比较的。
但是,一旦我编辑了列值,数据就会保存在会话中,但是如果我切换输入或关闭应用程序并重新打开,它会恢复到原来的状态。编辑未反映在摘要中 table。我做错了什么?
# Load libraries
library(DT)
library(gt)
library(shiny)
library(shinydashboard)
library(dplyr)
# Load data (run once for replication; in real use case will be a DB-connection)
#gtcars_tbl <- gtcars
#write.csv(gtcars_tbl, "gtcars_tbl.csv", row.names = FALSE)
# Simple UI
sidebar <- dashboardSidebar(
sidebarMenu(
menuItem("Summary table", tabName = "summary", icon = icon("project-diagram")),
menuItem("Edit table", tabName = "edit", icon = icon("project-diagram")),
uiOutput("country")
)
)
body <- dashboardBody(
tabItems(
tabItem(tabName = "summary",
h2("Summary of GT Cars"),
gt_output(outputId = "gt_filt_tbl")
),
tabItem(tabName = "edit",
h2("Editer GT Cars"),
DTOutput("edit")
)
)
)
ui <- dashboardPage(
dashboardHeader(title = "GT Cars"),
sidebar,
body)
# Define server functions
server <- function(input, output, session) {
# Load data
gtcars_tbl <- read.csv("gtcars_tbl.csv")
countries <- sort(as.vector(unique(gtcars_tbl$ctry_origin)))
# Create dropdown output
output$country <- renderUI({
selectInput("country", "Country", countries)
})
# Create reactive table
gt_tbl_react <- reactiveVal(NULL)
gt_tbl_react(gtcars_tbl)
# Create filtered table
gt_filt_tbl <- reactive({
req(input$country)
gt_tbl_react() %>%
filter(ctry_origin == input$country)
})
# Render summary table
output$gt_filt_tbl <- render_gt({
gt_filt_tbl() %>%
group_by(ctry_origin, mfr) %>%
summarise(
N = n(),
Avg_HP = mean(hp),
MSRP = mean(msrp)
) %>%
gt(
rowname_col = "ctry_origin",
groupname_col = "mfr")
})
# Render editable table
output$edit <- renderDT(
gt_tbl_react() %>%
filter(ctry_origin == input$country),
selection = 'none', editable = TRUE,
rownames = TRUE,
extensions = 'Buttons'
)
observeEvent(input$edit_cell_edit, {
gtcars_tbl[input$edit_cell_edit$row,input$edit_cell_edit$col] <<- input$edit_cell_edit$value
write.csv(gtcars_tbl, "gtcars_tbl.csv", row.names = FALSE)
})
}
# Run app
shinyApp(ui, server)
问题是 input$edit_cell_edit$row
和 input$edit_cell_edit$col
是根据显示的子集数据框提供的,而您正在更改完整数据框的值。
在observeEvent
-
中使用这个
observeEvent(input$edit_cell_edit, {
inds <- which(gtcars_tbl$ctry_origin == input$country)
gtcars_tbl[inds[input$edit_cell_edit$row],input$edit_cell_edit$col] <- input$edit_cell_edit$value
write.csv(gtcars_tbl, "gtcars_tbl.csv", row.names = FALSE)
})
我有一个应用程序,它从 SQL-db 获取数据,然后允许用户编辑它,这应该保存到数据库中。在 repex 中我使用了一个 CSV 文件,但逻辑应该仍然是可比较的。
但是,一旦我编辑了列值,数据就会保存在会话中,但是如果我切换输入或关闭应用程序并重新打开,它会恢复到原来的状态。编辑未反映在摘要中 table。我做错了什么?
# Load libraries
library(DT)
library(gt)
library(shiny)
library(shinydashboard)
library(dplyr)
# Load data (run once for replication; in real use case will be a DB-connection)
#gtcars_tbl <- gtcars
#write.csv(gtcars_tbl, "gtcars_tbl.csv", row.names = FALSE)
# Simple UI
sidebar <- dashboardSidebar(
sidebarMenu(
menuItem("Summary table", tabName = "summary", icon = icon("project-diagram")),
menuItem("Edit table", tabName = "edit", icon = icon("project-diagram")),
uiOutput("country")
)
)
body <- dashboardBody(
tabItems(
tabItem(tabName = "summary",
h2("Summary of GT Cars"),
gt_output(outputId = "gt_filt_tbl")
),
tabItem(tabName = "edit",
h2("Editer GT Cars"),
DTOutput("edit")
)
)
)
ui <- dashboardPage(
dashboardHeader(title = "GT Cars"),
sidebar,
body)
# Define server functions
server <- function(input, output, session) {
# Load data
gtcars_tbl <- read.csv("gtcars_tbl.csv")
countries <- sort(as.vector(unique(gtcars_tbl$ctry_origin)))
# Create dropdown output
output$country <- renderUI({
selectInput("country", "Country", countries)
})
# Create reactive table
gt_tbl_react <- reactiveVal(NULL)
gt_tbl_react(gtcars_tbl)
# Create filtered table
gt_filt_tbl <- reactive({
req(input$country)
gt_tbl_react() %>%
filter(ctry_origin == input$country)
})
# Render summary table
output$gt_filt_tbl <- render_gt({
gt_filt_tbl() %>%
group_by(ctry_origin, mfr) %>%
summarise(
N = n(),
Avg_HP = mean(hp),
MSRP = mean(msrp)
) %>%
gt(
rowname_col = "ctry_origin",
groupname_col = "mfr")
})
# Render editable table
output$edit <- renderDT(
gt_tbl_react() %>%
filter(ctry_origin == input$country),
selection = 'none', editable = TRUE,
rownames = TRUE,
extensions = 'Buttons'
)
observeEvent(input$edit_cell_edit, {
gtcars_tbl[input$edit_cell_edit$row,input$edit_cell_edit$col] <<- input$edit_cell_edit$value
write.csv(gtcars_tbl, "gtcars_tbl.csv", row.names = FALSE)
})
}
# Run app
shinyApp(ui, server)
问题是 input$edit_cell_edit$row
和 input$edit_cell_edit$col
是根据显示的子集数据框提供的,而您正在更改完整数据框的值。
在observeEvent
-
observeEvent(input$edit_cell_edit, {
inds <- which(gtcars_tbl$ctry_origin == input$country)
gtcars_tbl[inds[input$edit_cell_edit$row],input$edit_cell_edit$col] <- input$edit_cell_edit$value
write.csv(gtcars_tbl, "gtcars_tbl.csv", row.names = FALSE)
})