我以前通过对由'code-block-a'或'code-block-b'生成的reactive对象或reactiveValues进行事件观察或事件反应来完成此操作。我附加了3个小的shiny app示例,以使用不同的方法提供洞察力(希望这些会帮助回答原始问题 - 或者至少提供一些想法)。
该应用程序将在'code-block-a'中创建一个表格,其中行数等于sliderInput选择的行数。一旦更新了'event_a()' reactive,'code-block-b'就会对一个行进行子集处理。一旦'code-block-b'更新其对象'event_b()',就会显示一个模态框,其中显示所选行的表格。
library(shiny)
library(tidyverse)
ui <- fluidPage(
sliderInput("slide", "slide", value = 5, min = 1, max = 10),
actionButton("go", "go"),
)
server <- function(input, output, session) {
rv <- reactiveValues(tr1 = 0, el = 0)
final <- reactiveValues()
event_a <- eventReactive(input$go,{
nums <- seq(1, input$slide, by = 1)
l <- 1:length(nums)
tibble(Letter = letters[l],
Value = nums)
})
event_b <- eventReactive(event_a(), {
row <- sample(1:nrow(event_a()), 1)
event_a()[row,]
})
output$modal_plot <- renderTable({
event_b()
})
observeEvent(event_b(), {
showModal(modalDialog(title = "Table",
"This is a table",
tableOutput("modal_plot"),
inline = T))
})
}
shinyApp(ui, server)
如果你的所有 'code-block' 都是观察者,那么你可以使用在观察器内更新的响应式值。如果需要多个操作来触发下游事件,我发现这很灵活:
library(shiny)
library(tidyverse)
ui <- fluidPage(
sliderInput("slide", "slide", value = 5, min = 1, max = 10),
actionButton("go", "go"),
)
server <- function(input, output, session) {
rv <- reactiveValues(tr1 = 0, el = 0)
final <- reactiveValues()
event_a <- eventReactive(input$go,{
nums <- seq(1, input$slide, by = 1)
l <- 1:length(nums)
tibble(Letter = letters[l],
Value = nums)
})
observeEvent(event_a(),{
rv$el <- rv$el + 1
})
event_b <- eventReactive(rv$el, ignoreInit = T, {
row <- sample(1:nrow(event_a()), 1)
event_a()[row,]
})
observeEvent(event_b(), {
rv$tr1 <- rv$tr1 + 1
})
output$modal_plot <- renderTable({
event_b()
})
observeEvent(rv$tr1, ignoreInit = T, {
showModal(modalDialog(title = "Table",
"This is a table",
tableOutput("modal_plot"),
inline = T))
})
}
shinyApp(ui, server)
此外,如果您需要像循环一样迭代执行某些操作,以下示例可以描述上述过程,但每次仅在模态框中绘制一行数据并要求用户输入:
library(shiny)
library(tidyverse)
ui <- fluidPage(
sliderInput("slide", "slide", value = 5, min = 1, max = 10),
actionButton("go", "go"),
tableOutput("df"),
tableOutput("user_choices_table")
)
server <- function(input, output, session) {
rv <- reactiveValues(tr1 = 0, el = 0)
final <- reactiveValues()
data1 <- eventReactive(input$go,{
c <- seq(1, input$slide, by = 1)
l <- 1:length(c)
out_table <- tibble(Letter = letters[l],
Value = c)
return(out_table)
})
output$df <- renderTable({
data1()
})
num_iterations <- reactive({
nrow(data1())
})
observeEvent(data1(),{
rv$el <- rv$el + 1
})
data2 <- eventReactive(rv$el, ignoreInit = TRUE, {
data2 <- data1()[rv$el,]
return(data2)
})
output$modal_plot <- renderPlot({
d <- data2()
ggplot()+
geom_col(data = d, aes(x = Letter, y = Value, fill = Letter))+
theme_linedraw()
})
observeEvent(data2(), {
rv$tr1 <- rv$tr1 + 1
})
observeEvent(rv$tr1, ignoreInit = TRUE, {
showModal(modalDialog(title = "Make a Choice!",
"Is this a good selection?",
plotOutput("modal_plot"),
checkboxGroupInput("check", "Choose:",
choices = c("Yes" = "yes",
"No" = "no"),
inline = T),
footer = actionButton("modal_submit", "Submit")))
})
observeEvent(input$modal_submit, {
final[[as.character(rv$el)]] <- input$check
if(rv$el < num_iterations()){
rv$el <- rv$el + 1
} else {
rv$done <- rv$done + 1
}
})
observeEvent(input$modal_submit, {
removeModal()
})
final_choice <- eventReactive(rv$done, ignoreInit = TRUE,{
enframe(isolate(reactiveValuesToList(final))) %>%
mutate(name = as.numeric(name),
value = unlist(value)) %>%
arrange(name)
})
output$user_choices_table <- renderTable({
final_choice()
})
}
shinyApp(ui, server)
eventReactive()
,但最终我发现通过使用debounce
可以解决我的问题。 - johnny