R Shiny: 删除数据表中的行按钮

8
我正在开发一个R Shiny应用程序,用户可以控制数据表。他们可以添加新行到表中,或删除任何现有行。我的愿望是在表格中嵌入一个删除按钮,用户可以单击此按钮并删除该行。

以下是我的解决方案的当前状态,但它不一致地工作。添加按钮始终有效,但有时无法识别删除按钮。

示例失败。

  • 加载应用程序
  • 删除第2行
    • 有效
  • 删除第1行
    • 有效
  • 删除第3行
    • 无法识别按下按钮。

```

library(DT)

getRemoveButtons <- function(n, idS = "", lab = "Pit") {
  if (stringr::str_length(idS) > 0) idS <- paste0(idS, "-")
  ret <- shinyInput(actionButton, n,
                    'button_', label = "Remove",
                    onclick = sprintf('Shiny.onInputChange(\"%sremove_button_%s\",  this.id)' ,idS, lab))
  return (ret)
}
shinyInput <- function(FUN, len, id, ses, ...) {
  inputs <- character(len)
  for (i in seq_len(len)) {
    inputs[i] <- as.character(FUN(paste0(id, i), ...))
  }
  inputs
}

ui = shinyUI(fluidPage(
  fluidRow(DT::dataTableOutput("myTable")),
  fluidRow(actionButton("addRow", label = "Add Row",
                        icon = icon("plus"))))
)

server = function(input, output) {

  values <- reactiveValues()
  values$tab <- tibble(
    Row = 1:3L,
    Remove = getRemoveButtons(3, idS = "", lab = "Tab1"))

  proxyTable <- DT::dataTableProxy("tab")

  output$myTable <- DT::renderDataTable({
    DT::datatable(values$tab,
                  options = list(pageLength = 25,
                                 dom        = "rt"),
                  rownames = FALSE,
                  escape   = FALSE,
                  editable = TRUE)
  })

  observeEvent(input$remove_button_Tab1, {
    myTable <- values$tab
    s <- as.numeric(strsplit(input$remove_button_Tab1, "_")[[1]][2])
    myTable <- filter(myTable, row_number() != s)
    myTable <-
      mutate(myTable,
             Remove = getRemoveButtons(nrow(myTable), idS = "", lab = "Tab1"))
    replaceData(proxyTable, myTable, resetPaging = FALSE)
    values$tab <- myTable
  })
  observeEvent(input$addRow, {
    myTable <- isolate(values$tab)
    myTable <- select(myTable, Row)
    myTable <- bind_rows(
      myTable,
      tibble(Row = nrow(myTable) + 1))
    myTable <- mutate(myTable,
                      Remove = getRemoveButtons(nrow(myTable), idS = "", lab = "Tab1"))
    replaceData(proxyTable, myTable, resetPaging = FALSE)
    values$tab <- myTable
  })
}

shinyApp(ui = ui, server = server)
1个回答

6

好的,现在它可以正常工作了。问题在于尝试重复使用按钮的id。通过创建一个计数器并为每个新按钮分配一个以前从未使用过的id,现在它完美地工作了。修改后的代码如下。

```

library(DT)
library(dplyr)

getRemoveButton <- function(n, idS = "", lab = "Pit") {
  if (stringr::str_length(idS) > 0) idS <- paste0(idS, "-")
  ret <- shinyInput(actionButton, n,
                    'button_', label = "Remove",
                    onclick = sprintf('Shiny.onInputChange(\"%sremove_button_%s\",  this.id)' ,idS, lab))
  return (ret)
}

shinyInput <- function(FUN, n, id, ses, ...) {
  as.character(FUN(paste0(id, n), ...))
}

ui = shinyUI(fluidPage(
  fluidRow(DT::dataTableOutput("myTable")),
  fluidRow(actionButton("addRow", label = "Add Row",
                        icon = icon("plus"))))
)

server = function(input, output) {

  buttonCounter <- 3L

  values <- reactiveValues()
  values$tab <- tibble(
    Row = 1:3L,
    id = 1:3L) %>%
    rowwise() %>%
    mutate(Remove = getRemoveButton(id, idS = "", lab = "Tab1"))

  proxyTable <- DT::dataTableProxy("tab")

  output$myTable <- DT::renderDataTable({
    DT::datatable(values$tab,
                  options = list(pageLength = 25,
                                 dom        = "rt"),
                  rownames = FALSE,
                  escape   = FALSE,
                  editable = TRUE)
  })

  observeEvent(input$remove_button_Tab1, {
    myTable <- values$tab
    s <- as.numeric(strsplit(input$remove_button_Tab1, "_")[[1]][2])
    myTable <- filter(myTable, id != s)
    replaceData(proxyTable, myTable, resetPaging = FALSE)
    values$tab <- myTable
  })
  observeEvent(input$addRow, {
    buttonCounter <<- buttonCounter + 1L
    myTable <- isolate(values$tab)
    myTable <- bind_rows(
      myTable,
      tibble(Row = nrow(myTable) + 1) %>%
        mutate(id = buttonCounter,
               Remove = getRemoveButton(buttonCounter, idS = "", lab = "Tab1")))
    replaceData(proxyTable, myTable, resetPaging = FALSE)
    values$tab <- myTable
  })
}

shinyApp(ui = ui, server = server)

这个解决方案很棒,请问如果我们已经有一个数据框,你能否展示如何使用它呢?比如说我们的初始数据框是mtcars。谢谢。 - Angelo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接