简体   繁体   English

如何在 R Shiny 应用程序中存储反应变量的先前状态?

[英]How to store previous states of reactive variables in R Shiny application?

Let's imagine a Shiny app that generates a vector of 10 random words when the user clicks on an ActionButton.让我们想象一个 Shiny 应用程序,当用户点击一个 ActionButton 时,它会生成一个包含 10 个随机单词的向量。 These words are presented in a table (DT package) that allows the user to select the words/rows he is interested in in order to build a selection.这些单词显示在一个表格(DT 包)中,允许用户 select 他感兴趣的单词/行以构建选择。 This selection is transferred to another table (using "_rows_selected" input from DT datatable) and displayed.此选择被传输到另一个表(使用来自 DT 数据表的“_rows_selected”输入)并显示。 This is what the minimal example below does:这就是下面的最小示例所做的:

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)

However, if the user clicks the actionbutton again, new words are generated and the selection in the second table is therefore deleted.但是,如果用户再次单击操作按钮,则会生成新单词,因此会删除第二个表中的选择。 I would like the selection to keep track of previously selected words and add any new selection of words we have selected.我希望选择跟踪以前选择的单词并添加我们选择的任何新的单词选择。

How can I do this?我怎样才能做到这一点? How can I keep in memory the previous states of my reactive variable (frozen at the time of the generation of new words with a new click) and concatenate them to its currently selected words?如何在 memory 中保留我的反应变量的先前状态(在通过新点击生成新单词时冻结)并将它们连接到当前选择的单词?

I haven't found a solution so far, thank you in advance for your help!到目前为止我还没有找到解决方案,在此先感谢您的帮助!

You can store them in a reactive value, like this:您可以将它们存储在反应值中,如下所示:

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
})

By adapting a little bit the code proposed by Stéphane Laurent, I can propose this complete app that corresponds perfectly to what I wanted and what I had in mind when I asked my question.通过稍微修改 Stéphane Laurent 提出的代码,我可以提出这个完整的应用程序,该应用程序完全符合我的需求以及我提出问题时的想法。 It is possible that there is a more concise solution, in particular concerning the variables dat and all_words .可能有更简洁的解决方案,特别是关于变量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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM