上面 OP 的回答存在许多问题。
首先,observeEvent(input$Save 中存在范围界定问题。事件观察者是函数。因此mtcars <- mtcars ... 创建了全局mtcars 对象的本地(修改后的)副本,然后在事件观察者终止时将其丢弃。 output$table <- renderTable 中引用的 mtcars 是未更改的全局对象。这种情况的一个症状是output$table 显示的表格不包含analysed 列。
其次,动作按钮的id是save,而不是Save。 Dave 是它的标签。所以事件观察者无论如何都不会被触发。确认事件观察者(或其他 ractive)在您期望触发时被触发的一种好方法是简单地将 print 语句放入响应中。
要获得 OP 所需的功能,我们需要颠倒我最初建议的逻辑。当单击save 按钮时,我们需要保留当前未 选择的行。这表明将按钮的名称(id)更改为analyse(“分析”)是有意义的。
其次,要确保非反应式过滤数据集仅在单击保存按钮时更新(而不是在selectCyl选择输入中的selction更新时,我们需要isolate引用@987654336 @。
最后,为了克服上述范围问题,我们需要在事件观察器中使用全局赋值运算符<<-(或更一般地,assign)。
在下面的代码中,analysedCars 仅在单击 Analyse 按钮时更新。 filteredCars 会在 selectCyl 中的选择更改后立即更新。
请注意,filteredCars 允许“未分析”行:也就是说,行将被添加回过滤后的数据集中,以响应selectCyl 选择输入的更改。 analysedCars 不会发生这种情况。这似乎是 OP 的意图。
在未分析行之前,filteredCars 和 analysedCars 的行为之间的唯一区别是更新的时间。
library(shiny)
library(tidyverse)
ui <- fluidPage(
# Note the use of "- Show all -"="" to allow a "no filter" option
# Select mtcars by cylinders
selectInput(
inputId="cylSelect",
label="Filter by number of cylinders",
choices=c("- Show all -"="", sort(unique(mtcars$cyl))),
multiple=TRUE
),
# Action Button to Save analysed Data
actionButton("analyse","Analyse"),
# show datatable
tableOutput("table"),
tableOutput("filtab")
)
server <- function(input, output, session) {
#Define extra variable into the mtcars dataset.
inputDF <- mtcars %>%
rownames_to_column("Model") %>%
mutate(analysed=FALSE)
# Take a copy for delayed updates
analysedCars <- inputDF
filteredCars <- reactive({
df <- inputDF %>% filter(analysed == FALSE)
if (!is.null(input$cylSelect)) {
df <- df %>%
filter(!(cyl %in% input$cylSelect))
}
df
})
observeEvent(input$analyse,{
isolate({
analysedCars <<- analysedCars %>%
mutate(analysed = cyl %in% input$cylSelect) %>%
filter(!analysed)
})
analysedCars
})
output$table <- renderTable({
input$analyse
analysedCars
})
output$filtab <- renderTable({ filteredCars() })
}
shinyApp(ui = ui, server = server)