如何在正确位置使用 SelectInput 时保存在 DT 中所做的编辑

Posted

技术标签:

【中文标题】如何在正确位置使用 SelectInput 时保存在 DT 中所做的编辑【英文标题】:How to save edits made in DT while using SelectInput in correct position 【发布时间】:2019-11-26 01:50:41 【问题描述】:

当使用 SelectInput 选择输入的可编辑 DataTable(包 DT)时,所做的编辑不会保存在应有的位置。

选择特定变量会在第一行显示数据表中的第 50-60 行。编辑它们会将编辑保存在第一行而不是第 50-60 行。

在下面的示例中,您可以选择变量 versicolor 并删除 setosa。然后将 Petal.Length 编辑为随机数。编辑应该保存在第 51 行,但它保存在第 1 行。

我正在考虑一种基于索引列的解决方法,以便将编辑保存在行号 (indexrow) 中。但我不知道该怎么做。

#Packages
library(shiny)
library(shinyalert)
library(shinydashboard)
library(leaflet)
library(leaflet.extras)
library(DT)

#data
iris = iris

#Shiny-app (ui)
header = dashboardHeader(title = "SelectInput DataTable example")

sidebar = dashboardSidebar(selectInput("species", "Choose species:  ",    choices = iris$Species, selected = "setosa",  multiple = TRUE))

body = dashboardBody(fluidRow(dataTableOutput("table")))

ui = dashboardPage(skin = "red", header, sidebar, body)

#Server
server <- function(input, output, session) 


  output$table = DT::renderDataTable(iris[iris$Species %in% input$species,], editable = TRUE)

  proxy = dataTableProxy('table')

  observeEvent(input$table_cell_edit, 
    info = input$table_cell_edit
    str(info)
    i = info$row
    j = info$col
    v = info$value
    iris[i, j] <<- DT::coerceValue(v, iris[i, j])
    replaceData(proxy, iris, resetPaging = FALSE)  # important
  )


shinyApp(ui = ui, server = server)

【问题讨论】:

【参考方案1】:

试试这个:

#Packages
library(shiny)
library(shinydashboard)
library(DT)

#data
iris = iris

#Shiny-app (ui)
header = dashboardHeader(title = "SelectInput DataTable example")

sidebar = dashboardSidebar(selectInput("species", "Choose species: ", 
                                       choices = iris$Species, selected = "setosa",  multiple = TRUE))

body = dashboardBody(fluidRow(DT::dataTableOutput("table")))

ui = dashboardPage(skin = "red", header, sidebar, body)

# javascript 
js <- function(rows)
  c(
    "function(settings)",
    "  var table = settings.oInstance.api();",
    sprintf("  var indices = [%s];", paste0(rows-1, collapse = ",")),
    "  table.rows(indices).remove().draw();",
    ""
  )


#Server
server <- function(input, output, session) 

  dat <- reactiveVal(iris)

  Rows <- reactive(
    which(iris$Species %in% input$species)
  )

  output$table = DT::renderDataTable(
    rows <- setdiff(1:nrow(iris), Rows())
    datatable(
      dat(), 
      editable = TRUE,
      options = list(
        initComplete = JS(js(rows))
      )
    )
  , server = FALSE)

  observeEvent(input$table_cell_edit, 
    info = input$table_cell_edit
    info$row = Rows()[info$row+1] - 1
    dat(editData(dat(), info))
  )


shinyApp(ui = ui, server = server)

【讨论】:

嗨史蒂芬。您使用 iris 数据集的示例完美无缺!但是当我将它调整为我自己的数据集时,它无法正常工作。编辑未保存在应有的位置。 @Rprogrammer 是的,对不起,我想我明白了。它适用于虹膜,因为该物种被分组在连续的行中。您的问题很困难,因为当更改 input$species 时会重新呈现数据表。我会尝试再考虑一下,但我不确定能否实现。 第一次编辑单元格时不会保存,但编辑同一个单元格两次确实有效。 @Rprogrammer 奇怪,这对我有用。让我重试。 @Rprogrammer 我确认这对我来说很好。与您发布的应用相比,您有什么改变吗?

以上是关于如何在正确位置使用 SelectInput 时保存在 DT 中所做的编辑的主要内容,如果未能解决你的问题,请参考以下文章

未选择值时如何更改 R Shiny 'selectInput' 值选择显示空间背景颜色?

如何对齐闪亮的输入框,特别是 selectInput 和 numericInput

Rshiny:如何将 renderUI 输出传递给 Selectinput 中的 chocies 参数

反应式 selectInput 选项和选定值无法正确重置为 NULL

如何在 RMarkdown 中使用 Shiny 进行嵌套选择 selectInput()?

Rails jquery sortable无法正确保存位置