Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create On load Event or default event in shiny?

I am new to shiny as well as stackoverflow and looking for some help with a problem that I am currently stuck at. I am trying to build a shiny app which collects some inputs from the user and creates visualization based on inputs on click of a button. Currently, that works fine, but one of the major ask is that, when the app loads for the first time, it shall have visualization prepared based on the default inputs.

I am pasting a sample code, which can explain the issue I am facing:

UI.R

  #loading shiny
  library(shiny)
  
  ui<-shinyUI(fluidPage(
    titlePanel("Iris Dataset"),
    sidebarLayout(
      sidebarPanel(
        radioButtons("x", "Select X-axis:",
                     list("Sepal.Length"='a', "Sepal.Width"='b', "Petal.Length"='c', "Petal.Width"='d')),
        radioButtons("y", "Select Y-axis:",
                     list("Sepal.Length"='e', "Sepal.Width"='f', "Petal.Length"='g', "Petal.Width"='h')),
        actionButton("action","Submit")
      ),
      mainPanel(
        plotOutput("distPlot")
      )
    )
  ))
  
  #SERVER.R
  library(shiny)
  
  #loading shiny
  server<-shinyServer(function(input, output) {
    
    observeEvent(input$action,{
    output$distPlot <- renderPlot({if(input$x=='a'){i<-1}
      
      if(input$x=='b'){i<-2}
      
      if(input$x=='c'){i<-3}
      
      if(input$x=='d'){i<-4}
      
      if(input$y=='e'){j<-1}
      
      if(input$y=='f'){j<-2}
      
      if(input$y=='g'){j<-3}
      
      if(input$y=='h'){j<-4}
      
      s    <- iris[, i]
      k    <- iris[, j]
      plot(s,k)
    })
  })
  })
  
  
  shinyApp(ui<-ui, server<-server)

Now if you run this app, you would see that the inputs are selected at the first screen after load (which is as desired) but the visualization appears only after clicking "Submit" button, this is because of the observer event. In the actual app, there are calculation being performed after capturing the inputs at the click of the button. Hence, the calculation triggers only when the actionButton is clicked

Is there a way, we can still keep the "Submit" button and its observe event, but automatically trigger the visualization or the action performed within the observe event at the start i.e. when the app loads for the first time.

like image 967
WiseChirag Avatar asked Feb 20 '18 21:02

WiseChirag


1 Answers

Using renderPlot or other render functions inside observeEvent is considered bad practice. What you are looking for is a reactive object that represents the plot parameters. You can then access this reactive object inside your renderPlot context. Here is an example

library(shiny)

ui <- shinyUI(fluidPage(
  titlePanel("Iris Dataset"),
  sidebarLayout(
    sidebarPanel(
      radioButtons("x", "Select X-axis:",
                   list("Sepal.Length" = 'a', "Sepal.Width" = 'b',
                        "Petal.Length" = 'c', "Petal.Width" = 'd')),
      radioButtons("y", "Select Y-axis:",
                   list("Sepal.Length" = 'e', "Sepal.Width" = 'f', 
                        "Petal.Length" = 'g', "Petal.Width" = 'h')),
      actionButton("action", "Submit")
    ),
    mainPanel(
      plotOutput("distPlot")
    )
  )
))

server <- shinyServer(function(input, output) {

  user_choice <- eventReactive(input$action,{
    if (input$x == 'a'){i <- 1}    
    if (input$x == 'b'){i <- 2}    
    if (input$x == 'c'){i <- 3}    
    if (input$x == 'd'){i <- 4}    
    if (input$y == 'e'){j <- 1}    
    if (input$y == 'f'){j <- 2}    
    if (input$y == 'g'){j <- 3}    
    if (input$y == 'h'){j <- 4}

    return(c(i, j))

    ## use ignoreNULL to fire the event at startup
  }, ignoreNULL = FALSE)

  output$distPlot <- renderPlot({
    uc <- user_choice()
    plot(iris[, uc[1]], iris[, uc[2]])
  })
})


shinyApp(ui = ui, server = server)

The object user_choice will get updated whenever a user clicks the button or the app starts.

There is also an ignoreNULL parameter in observeEvent but for some reason, that does not yield the same result.

like image 96
Gregor de Cillia Avatar answered Sep 23 '22 21:09

Gregor de Cillia