【问题标题】:How to store previous states of reactive variables in R Shiny application?如何在 R Shiny 应用程序中存储反应变量的先前状态?
【发布时间】:2020-12-04 11:19:05
【问题描述】:

让我们想象一个 Shiny 应用程序,当用户点击一个 ActionButton 时,它会生成一个包含 10 个随机单词的向量。这些词显示在一个表格(DT 包)中,允许用户选择他感兴趣的词/行以构建选择。此选择被传输到另一个表(使用来自 DT 数据表的“_rows_selected”输入)并显示。这就是下面的最小示例所做的:

library(shiny)
library(DT)

ui <- fluidPage(
  actionButton("generate", "New random words"),
  h5("Original data"),
  dataTableOutput("results"),
  br(),
  h5("Selected data"),
  dataTableOutput("selection")
)

server <- function(input, output, session) {
  
  generated_data <- eventReactive(input$generate, {
    random_words <- sapply(1:10, function(x) sample(letters, x) %>% paste(collapse=""))
    data.frame(ID=1:10, Word=random_words)
  })
  
  output$results <- renderDataTable(
    datatable(generated_data(), rownames = FALSE)
  )
  
  output$selection <- renderDataTable(
    generated_data()[input$results_rows_selected,] %>%
      datatable(rownames=FALSE)
  )
}

shinyApp(ui, server)

但是,如果用户再次单击操作按钮,则会生成新词,因此会删除第二个表中的选择。我希望选择跟踪以前选择的单词并添加我们选择的任何新单词。

我该怎么做?我怎样才能记住我的反应变量的先前状态(在通过新点击生成新单词时冻结)并将它们连接到其当前选择的单词?

目前还没有找到解决办法,先谢谢你的帮助!

【问题讨论】:

    标签: r shiny


    【解决方案1】:

    您可以将它们存储在反应值中,如下所示:

    all_words <- reactiveVal(data.frame(ID = integer(0), Word = character(0)))
    
    generated_data <- eventReactive(input$generate, {
      random_words <- 
        sapply(1:10, function(x) sample(letters, x) %>% paste(collapse=""))
      dat <- data.frame(ID=1:10, Word=random_words)
      all_words(rbind(all_words(), dat))
      dat
    })
    

    【讨论】:

    • 非常感谢您提供这一重要元素。为了更好地理解:reactiveVal(我没有想到)是否允许在这里做一个简单的反应式(我尝试过但没有成功)不能做的事情?如果是,为什么?
    • 但是如果我在我的最小应用程序中插入你的代码(通过修改你的倒数第二行以遵守我的规范 all_words(rbind(all_words(), dat[input$results_rows_selected,])))那么我还有一个问题:选择的随机词不是正确的。这些词是在新的词集 (dat) 中选择的,带有旧的行引用...
    【解决方案2】:

    通过稍微修改一下 Stéphane Laurent 提出的代码,我可以提出这个完整的应用程序,该应用程序完全符合我的需求以及我提出问题时的想法。 可能有更简洁的解决方案,特别是关于变量datall_words

    library(shiny)
    library(DT)
    
    ui <- fluidPage(
      actionButton("generate", "New random words"),
      h5("Original data"),
      dataTableOutput("results"),
      br(),
      h5("Selected data"),
      dataTableOutput("selection")
    )
    
    server <- function(input, output, session) {
      
      all_words <- reactiveVal(data.frame(ID = integer(0), Word = character(0)))
      dat <- data.frame(ID=integer(0), Word=character(0))
      
      generated_data <- eventReactive(input$generate, {
        all_words(rbind(all_words(), dat[input$results_rows_selected,]))
        random_words <- 
          sapply(1:10, function(x) sample(letters, x) %>% paste(collapse=""))
        dat <<- data.frame(ID=1:10, Word=random_words)
        dat
      })
      
      output$results <- renderDataTable(
        datatable(generated_data(), rownames = FALSE)
      )
      
      output$selection <- renderDataTable(
        rbind(generated_data()[input$results_rows_selected,], all_words()) %>%
          datatable(rownames=FALSE)
      )
    }
    
    shinyApp(ui, server)
    

    【讨论】:

      猜你喜欢
      • 2019-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-18
      • 2015-09-18
      • 2014-07-18
      • 2018-10-24
      相关资源
      最近更新 更多