0

I am building a shiny application which visualises the output of a complex model. The model is in a script which is sourced by the shiny app. I want to change one input of the model calculation with selectInput and plot the output model accordingly.

Below is a simplied version of the model's source script and the app.

model.R

#data of the model 
yellow_data <- c (10,28,14,40)
green_data <- c(20,40,50,90)
red_data <- c(50,50,50,80)

third_data <- c(30,32,3100,500)

data_model <- data.frame(yellow_data, green_data, red_data)

#the variable that should be updated by selectInput in the app.R
selected_data <- "yellow_data"

#the model output which should change according to changes in selected_data
model_output <- union(data_model[[selected_data]] * 200, third_data)

I want to change the value of the variable selected_data from the app.

app.R

library(shiny)

source("model.R")


ui <- fluidPage(
  
selectInput(inputId = "select_data", label = "SELECT DATA", choices = c("Yellow" = "yellow_data",
                                                                          "Green" = "green_data",
                                                                          "Red" = "red_data")),  
  plotlyOutput(outputId = "plot_model_output")
)

server <- function(input, output, session) {
  
  output$plot_model_output <- renderPlotly({ 
    
    selected_data_Change <- reactive({
      switch(input$select_data,
             "Yellow" = "yellow_data",
             "Green" = "green_data",
             "Red" = "red_data") 
    })
    
    selected_data <<- selected_data_Change()
       
    fig <- plot_ly(x = ~c(1:8), y = ~model_output, name = 'model output', type = 'scatter', mode ='lines')
   fig
  
  })
}
shinyApp(ui, server)

As you can see in app.R, I tried to update with selectInput the global variable selected_data which is used to compute model_output in model.R, which is sourced in app.R.

I would like the model_output to update and reflect according to selectInput.

I really hope you can help. Thank you

jhonccc
  • 59
  • 5

1 Answers1

0

Perhaps you are looking for this

ui <- fluidPage(
  
  selectInput(inputId = "select_data", label = "SELECT DATA", choices = c("Yellow" = "yellow_data",
                                                                          "Green" = "green_data",
                                                                          "Red" = "red_data")),  
  plotlyOutput(outputId = "plot_model_output")
)

server <- function(input, output, session) {
  
  output$plot_model_output <- renderPlotly({ 
    
    #the model output which should change according to changes in selected_data
    model_output <- c(data_model[,as.character(input$select_data)]*200, third_data)
    
    fig <- plot_ly(x = ~c(1:8), y = ~model_output, name = 'model output', type = 'scatter', mode ='lines')
    fig
    
  })
}
shinyApp(ui, server)
YBS
  • 19,324
  • 2
  • 9
  • 27
  • thanks, model_output in the real model.R is achieved after many computations and interactions with other data which change its structure. This fix works for this simplified example but in reality, I would need to insert all the computations of model.R in output$plot_model_output of app.R which is not ideal because there are both long scripts. I tried also with inserting the source(model.R) in output$plot_model_output or with observeEvent but nothing worked. Do you know if there is a way? thank you for your help – jhonccc Oct 17 '21 at 07:22
  • Sure there is a way. If this MRE is not appropriate, then you need to create a proper [MRE](https://stackoverflow.com/help/minimal-reproducible-example) so that you can implement the answer in your real use case. – YBS Oct 17 '21 at 12:00
  • I have posted a more detailed MRE here https://stackoverflow.com/questions/69622945/r-shiny-selectinput-to-update-variable-in-sourced-script I hope you can help. Thank you – jhonccc Oct 18 '21 at 21:56
  • @jhonccc, I am not sure I understand the question. This should work without modifying your other source programs. You call the model you want from `model.R`. Please check how `union()` works. Duplicates are removed, resulting in different length for `x` and `y`. – YBS Oct 18 '21 at 23:58
  • Thanks, I think what I am looking for is to wrap the script into a function or a module so that can be called with a reactive. I found this collection of resources which I hope you can find useful beta.rstudioconnect.com/content/2816/Shiny-Modules.html but I am new to the topic and I have not figure it out yet what would be the most efficient way. Any tip is appreciated. thanks – jhonccc Oct 19 '21 at 21:55