类型"closure"的对象在R Shiny中不可子集化 [英] object of type ‘closure’ is not subsettable in R Shiny

查看:75
本文介绍了类型"closure"的对象在R Shiny中不可子集化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I would like to add buttons to my DT (one for each row - in first column). When I click on the button it should remove the row from DT. I wrote a code:

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, ]
    })

  }
)

但是不幸的是,我收到错误消息:"closure"类型的对象不可子集.values $ data必须保留为reactValues,因为它只是我的项目的一部分,我在其他函数中使用它.那么如何编写df以使程序正常工作?

But unfortunately I get error: object of type ‘closure’ is not subsettable. values$data has to stay as reactiveValues because it is only fragment of my project and I use it in others functions. So how can I write df to make my program working?

推荐答案

出现此错误的原因是您将 df 称为 df $ data ,即如果它是 reactiveValues ,则更正.但是, df 是一种反应式,仅返回一个对象,因此您应该使用 df()对其进行调用.

The reason for the error is that you call the df as df$data, which would be correct if it was a reactiveValues. However, df is a reactive which returns just one object, so you should just call it with df().

对于您的问题,您可以创建一个 reactiveVal 来保存应删除的行.请注意,您应该自己进行一些调整,例如添加 observeEvent(values $ data,{rows_to_remove(NULL)})之类的东西,这样 rows_to_remove()对象是输入数据更改时重置为NULL.另一种方法是使整个数据框成为 reactiveVal ,并使用观察者对其进行更新.

For your issue, you could make a reactiveVal that holds the rows that should be removed. Please note that you should tweak this a little yourself, for example add something like observeEvent(values$data, {rows_to_remove(NULL)}) so the rows_to_remove() object is reset to NULL when the input data changes. Another approach would be to make the entire dataframe a reactiveVal, and use observers to update it.

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

Working example below, hope this helps!

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

  }
)

这篇关于类型"closure"的对象在R Shiny中不可子集化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆