简体   繁体   中英

shiny - reactive() to select between two reactive()

I'm making an app in Shiny which allows users to upload data or upload a save file.

If a user uploads new data then the flow looks like:

Upload Files >> Select Sheets >> Select Columns >> Sentence Tokenization >> Word Tokenization >> Graphics

Originally, I had been using observe() statements with reactiveValues() so at each step, I stored off the results into a reactiveValues(). This enabled the save file upload to work like:

Upload Save File >> Set sentences >> Set words >> Graphics

I would like to be able to accomplish something similar but using reactive() statements. So, given that I have uploadedFiles = reactive() and uploadedSave = reactive() how do I write a reactive with the following pseudo code:

rawText = reactive({
  if uploadedFiles() flushes reactivity then uploadedFiles()
  else if uploadedSave() flushes reactivity then uploadedSave()
  else NULL
})

I don't have an "error" I'm trying to troubleshoot, just trying to think through the process of using a reactive to act like a 'most recently flushed' gate to allow my data flow to start from two different places and converge to a single one.

I'm going to show how I do it, but I have a feeling it is not a great method. I'm interested in hearing what the best method is and what's wrong with mine.

new_react <- reactiveValues()
new_react$FilesReact <- 0 
new_react$SaveReact <- 0

invalidate <- function(x) x <- x+1

uploadedSave <- eventReactive(new_react$SaveReact,{ 
   # Set sentences >> Set words >> Graphics
})


uploadedFiles <- eventReactive(new_react$FilesReact,{ 
  # Select Sheets >> Select Columns >> Sentence Tokenization >> Word Tokenization >> Graphics
})

## I don't know how you are going to determine whether it's a data file
# or a save file...

if (its_a_save_file) {
  new_react$SaveReact <- invalidate(new_react$SaveReact)
  uploadedSave()
}else if (its_a_data_file) {
  new_react$FilesReact <- invalidate(new_react$FilesReact)
  uploadedFiles()

So basically I just define two reactive values which when invalidated by that simple function, will allow for the reactive functions, uploadedSave() or uploadedFiles() to be called.

Edit: To me, this just looks like a way to force eventReactive() to work like observeEvent()

Without more code, it is hard to be specific. Here is an app. that displays a different value based on what is the last control used. The controls are monitored using observeEvent() and each will put its input into a reactive value. Then the output just works with whatever is in the reactive value. For your case you need to have an observeEvent() for each of the controls you are using to do file and save uploads. Then they each put their file into a common reactiveValue and that value is used for further processing.

library(shiny)

app<-shinyApp(
  ui=(fluidPage(sliderInput("First", min=1, max=10, label="Slider", value=1),
                actionButton("Second", label="Second Button"),
                textOutput("OutText"))
    ),

  server=function(input,output){

    RV<-reactiveValues(data=NULL)

    observeEvent(input$First,
      RV$Text<-input$First)

    observeEvent(input$Second,
       RV$Text<-"Second")

    output$OutText<-renderText({
      req(RV$Text)
      RV$Text
    })
  }
)

runApp(app)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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