“闭包”类型的对象在 R Shiny 中不可子集化
object of type ‘closure’ is not subsettable in R Shiny
我想向我的 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 来让我的程序运行呢?
错误的原因是您将 df
称为 df$data
,如果它是 reactiveValues
,这将是正确的。然而,df
是一个 returns 只是一个对象的反应,所以你应该用 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
})
}
)
我想向我的 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 来让我的程序运行呢?
错误的原因是您将 df
称为 df$data
,如果它是 reactiveValues
,这将是正确的。然而,df
是一个 returns 只是一个对象的反应,所以你应该用 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
})
}
)