【问题标题】:object of type ‘closure’ is not subsettable in R Shiny“闭包”类型的对象在 R Shiny 中不是子集
【发布时间】:2018-06-22 16:32:54
【问题描述】:

我想向我的 DT 添加按钮(每行一个 - 在第一列中)。当我单击按钮时,它应该从 DT 中删除该行。我写了一段代码:

library(shiny)
library(DT)

shinyApp(
  ui <- fluidPage(DT::dataTableOutput("data")),

  server <- function(input, output) {

    values <- reactiveValues(data = NULL)

    values$data <- as.data.frame(
      cbind(c("a", "d", "b", "c", "e", "f"),
        c(1463, 159, 54, 52, 52, 220),
        c(0.7315, 0.0795, 0.027, 0.026, 0.026, 0.11)
      )
    )

    shinyInput <- function(FUN, len, id, ...) {
      inputs <- character(len)
      for (i in seq_len(len)) {
        inputs[i] <- as.character(FUN(paste0(id, i), ...))
      }
      inputs
    }

    df <- reactive({
      data = data.frame(
        Delete = shinyInput(actionButton, nrow(values$data), 'button_', label = "Remove", onclick = 'Shiny.onInputChange(\"select_button\",  this.id)'),
        as.data.frame(values$data),
        stringsAsFactors = FALSE,
        row.names = 1:nrow(values$data)
      )
    })

    output$data <- DT::renderDataTable(
      df$data, server = FALSE, escape = FALSE, selection = 'none'
    )

    observeEvent(input$select_button, {
      selectedRow <- as.numeric(strsplit(input$select_button, "_")[[1]][2])
      df$data <- df$data[rownames(df$data) != selectedRow, ]
    })

  }
)

但不幸的是,我得到了错误:“闭包”类型的对象不是子集。 values$data 必须保留为 reactiveValues,因为它只是我项目的一部分,我在其他功能中使用它。那么如何编写 df 来让我的程序正常运行呢?

【问题讨论】:

    标签: r button shiny dt reactive


    【解决方案1】:

    错误的原因是您将df 称为df$data,如果它是reactiveValues 则正确。然而,df 是一个响应式,它只返回一个对象,所以你应该用df() 调用它。

    对于您的问题,您可以创建一个 reactiveVal 来保存应删除的行。请注意,您应该自己稍微调整一下,例如添加类似 observeEvent(values$data, {rows_to_remove(NULL)}) 的内容,以便在输入数据更改时将 rows_to_remove() 对象重置为 NULL。另一种方法是将整个数据框设为reactiveVal,并使用观察者对其进行更新。

    下面的工作示例,希望对您有所帮助!

    library(shiny)
    library(DT)
    
    shinyApp(
      ui <- fluidPage(DT::dataTableOutput("data")),
    
      server <- function(input, output) {
    
        values <- reactiveValues(data = NULL)
    
        values$data <- as.data.frame(
          cbind(c("a", "d", "b", "c", "e", "f"),
                c(1463, 159, 54, 52, 52, 220),
                c(0.7315, 0.0795, 0.027, 0.026, 0.026, 0.11)
          )
        )
    
        shinyInput <- function(FUN, len, id, ...) {
          inputs <- character(len)
          for (i in seq_len(len)) {
            inputs[i] <- as.character(FUN(paste0(id, i), ...))
          }
          inputs
        }
    
    
        rows_to_remove <- reactiveVal()
    
        df <- reactive({
          data = data.frame(
            Delete = shinyInput(actionButton, nrow(values$data), 'button_', label = "Remove", onclick = 'Shiny.onInputChange(\"select_button\",  this.id)'),
            as.data.frame(values$data),
            stringsAsFactors = FALSE,
            row.names = 1:nrow(values$data)
          )
          data[!rownames(data) %in% rows_to_remove(), ]
        })
    
        output$data <- DT::renderDataTable(
          df(), server = FALSE, escape = FALSE, selection = 'none'
        )
    
        observeEvent(input$select_button, {
          selectedRow <- as.numeric(strsplit(input$select_button, "_")[[1]][2])
          rows_to_remove(c(rows_to_remove(),selectedRow)) # update the rows to remove
        })
    
      }
    )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-30
      相关资源
      最近更新 更多