假设我有一个reactive
返回 的控件data.frame
。我希望我的某些控件仅依赖于其列的子集,也就是说,只有当任何“相关”列(此处rel_1
和rel_2
)中的值发生变化时,它才会触发,而“不相关”列(此处irr_1
和irr_2
)中的更改不应触发刷新。
我以为创建一个reactive
只返回相关列的按钮就可以解决问题,但以下代码显示所有按钮都会触发刷新verbatimTextOutput
。我的预期是,按下“更改不相关列”按钮不会触发刷新,因为相关列中的值保持不变。
library(shiny)
library(DT)
library(dplyr)
library(glue)
dat <- tibble(
rel_1 = LETTERS[1:3],
rel_2 = letters[1:3],
irr_1 = 1:3,
irr_2 = 101:103
)
ui <- fluidPage(
fluidRow(
column(
width = 4,
actionButton("chng_all", "Change All Columns")
),
column(
width = 4,
actionButton("chng_irr", "Change Irrelevant Columns")
),
column(
width = 4,
actionButton("chng_rel", "Change Relevant Columns")
)
),
fluidRow(
column(
width = 12,
DTOutput("tbl")
)
),
fluidRow(
column(
width = 12,
verbatimTextOutput("dbg")
)
)
)
server <- function(input, output, session) {
my_data <- reactiveVal(dat)
change_values <- function(data, cols) {
data %>%
mutate(
across(all_of(cols),
~ if (is.numeric(.x)) sample(100, 3) else sample(LETTERS, 3))
)
}
relevant_data <- reactive(
my_data() %>%
select(starts_with("rel"))
)
observe({
my_data(change_values(my_data(), c(paste0("irr_", 1:2),
paste0("rel_", 1:2))))
}) %>%
bindEvent(input$chng_all)
observe({
my_data(change_values(my_data(), paste0("irr_", 1:2)))
}) %>%
bindEvent(input$chng_irr)
observe({
my_data(change_values(my_data(), paste0("rel_", 1:2)))
}) %>%
bindEvent(input$chng_rel)
output$tbl <- renderDT(
datatable(my_data())
)
output$dbg <- renderPrint({
glue("Relevant Data Last Changed: {Sys.time()}")
}) %>%
bindEvent(relevant_data())
}
shinyApp(ui, server)
reactiveVal
我们可以通过使用而不是来实现所需的行为reactive
:Winston Chang 对此的解释如下:
另请参阅此相关博客文章。