Keith
Keith

Reputation: 113

Output Forecast Plot and Forecast in Shiny App for R

I am trying to build a tool where the user can select a number of parameters (e.g partner, budget, month, year) and get back a foretasted value for next months metric.

I have built several external functions to perform the task. Each function performs some tasks and passes the data onto the next function and the final function builds four models, forecasts using those models, builds the ggplots and stores them in a list which one can access once the functions are run.

How do I extract the plots and forecasts to be shown through a Shiny App?

UI:

ui <- fluidPage(
  titlePanel("Forecasting Tool"),

  sidebarLayout(
    sidebarPanel(

  selectInput("Partner", h3("Partner"), 
      choices = list("all", "dsp","search","social"), selected = "all"),

       numericInput("Budget", 
           h3("Budget"), 
           value = 10000),

  selectInput("Month", h3("Month"), 
              choices = list("January", "February", "March", "April","May", 
                        "June", "July", "August", "September", "October", 
                        "November", "December"), 
            selected = "January"),

  selectInput("Year", h3("Year"), 
              choices = list(2018,2019), 
              selected = 2019),


   submitButton("Submit"), h3("")),

mainPanel(plotOutput("plot"))

  )
)

How do I build my server function such that it recognizes that the submit button has been triggered and runs the external functions?

my final function is called reg_mod and it triggers all the other functions, and then returns the final objects in a list (plots, forecasts, etc) the input it takes is as follows:

reg_mod(partner, budget, month, year)

Can I access the objects and output them in the server function based on user input? for instance:

plot = reg_mod(input$Partner, input$Budget, input$Month, input$year)

output$plot = renderPlot(plot[[1]])

where plot[[1]] calls the first object which is a plot from reg_mod

EDIT:

So here is an example of a helper function which creates some data and outputs a plot which I want to source into a shiny App, similar to what I want to do. (note, the only month selection option is "August" and year 2017 which is fine, can just run the app and run the default).

Helper = function(partner, budget, month, year){

 nums = seq(0 , 10, length.out = 100)

 Registrations = 5 + 2*rnorm(100, 20, 7)*nums
 dates = seq.Date(as.Date("2017-01-01"), as.Date("2017-04-10"), by ="days")

  Registrations = data.frame(Date = dates, Registrations = Registrations)

  if(partner == "dsp" & month == "August" & year == 2017){

    Registrations$Registrations = 0.5*budget*Registrations$Registrations
  }

  if(partner == "search" & month == "August" & year == 2017){

    Registrations$Registrations = 2*budget*Registrations$Registrations

  }

  if(partner == "social" & month == "August" & year == 2017){

    Registrations$Registrations = budget*Registrations$Registrations

  }

  Plot = ggplot(data = Registrations, aes(x = Date)) + 
    geom_line(aes(y = Registrations, colour = "Actual"), size = 1)

  List_Read = list("Plot" = Plot)

  return(List_Read)

}

and here are my UI and Server functions:

library(shiny)
library(ggplot2)
# Define UI for application that outputs ggplot
ui <-  fluidPage(
  titlePanel("Forecasting Tool"),

  sidebarLayout(
    sidebarPanel(

     selectInput("Partner", h3("Partner"), 
            choices = list("all", "dsp","search","social"), selected="dsp"),

  numericInput("Budget", 
               h3("Budget"), 
               value = 100),

selectInput("Month", h3("Month"), 
              choices = list("January", "February", "March", "April","May", 
              "June", "July",  "August", "September", "October", "November", 
              "December"), 
              selected = "August"),

  selectInput("Year", h3("Year"), 
              choices = list(2017,2018), 
              selected = 2017),


       submitButton("Submit"), h3("")),

mainPanel(plotOutput("plot"))

 )
)
# Define server logic required to output ggplot from helper function
server <- function(input, output, session) {

  source("C:/Users/ksiopes/Documents/Ad Hoc/Survival/Prefinal Insights 
   Function Files/For Shiny Function/Testing/Helper3.R", 
     local = FALSE)

  plot_List = eventReactive(input$Submit,{

    Helper(input$Partner, input$Budget, input$Month, input$Year)

  })

  #Output the plot
  output$plot<- renderPlot({
    plot = plot_List()
    plot[[1]]
  })

}

# Run the application 
shinyApp(ui = ui, server = server)

Edit 2:

library(shiny)
library(ggplot2)


source("C:/Users/ksiopes/Documents/Ad Hoc/Survival/Prefinal Insights 
Function Files/For Shiny Function/Testing/Helper3.R", local = TRUE)

# Define UI for application that uses function to create random data and 
output ggplot
ui <-  fluidPage(
  titlePanel("Forecasting Tool"),

  sidebarLayout(
    sidebarPanel(

      selectInput("Partner", h3("Partner"), 
              choices = list("all", "dsp","search","social"), selected = 
"dsp"),

      numericInput("Budget", 
                   h3("Budget"), 
                   value = 100),

      selectInput("Month", h3("Month"), 
                  choices = list("January", "February", "March", 
                   "April","May", "June", "July", "August", "September", 
                    "October", "November", "December"), 
              selected = "August"),

      selectInput("Year", h3("Year"), 
                  choices = list(2017,2018), 
                  selected = 2017),


      submitButton("Submit"), h3("")),

    mainPanel(plotOutput("plot"))

  )
)

# Define server logic required to run sourced function and output ggplot
server <- function(input, output, session) {


  plot_List = eventReactive(input$Submit,{



    Helper(input$Partner, input$Budget, input$Month, input$Year)


  })
    #Output the plot
    output$plot<- renderPlot({
    plot = plot_List()
    plot[[1]]

    })



}

# Run the application 
shinyApp(ui = ui, server = server)

Upvotes: 1

Views: 1053

Answers (1)

Chabo
Chabo

Reputation: 3000

Here is a general framework on how to go about this:

Loading in external functions to a shiny app requires a little extra work as opposed to a local script, but not much. We can still use the source function, the only difference is local=T must be set, and the function must be placed in the app directory. One the function is sourced, we can pass user inputs to it relatively easily.

Step 1) Save script with function in app directory (where server.R & ui.R or app.R is)

Step 2) Source the function

#Basically source the path to the function file you put in the app directory
source("your-app-dir/functions.R")

Step 3) Use the function, output the plot

server.R

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

#Function reg_mod in this file
source("your-app-dir/functions.R")

#Assuming the return of reg_mod is correct
plot_List<-eventReactive(input$Submit, {

reg_mod(input$Partner, input$Budget, input$Month, input$year)

})

#Output the plot
output$plot<- renderPlot({
plot<-plot_List()
plot[[1]] 
})


}

Additional help about using external functions in Shiny can be found here

Additional help regarding use of reactive environments in this example here

Edit: The fix to the graph not rendering is you are not activating your function to run since you are using an incorrect ui element. It should be actionButton not submitButton

actionButton("Submit", "Submit"), Use this instead

Full Code

library(shiny)
library(ggplot2)


source("Helper3.R", local = TRUE)

# Define UI for application that uses function to create random data and 

ui <-  fluidPage(
  titlePanel("Forecasting Tool"),

  sidebarLayout(
    sidebarPanel(

      selectInput("Partner", h3("Partner"), 
                  choices = list("all", "dsp","search","social"), selected = 
                    "dsp"),

      numericInput("Budget", 
                   h3("Budget"), 
                   value = 100),

      selectInput("Month", h3("Month"), 
                  choices = list("January", "February", "March", 
                                 "April","May", "June", "July", "August", "September", 
                                 "October", "November", "December"), 
                  selected = "August"),

      selectInput("Year", h3("Year"), 
                  choices = list(2017,2018), 
                  selected = 2017),


      actionButton("Submit", "Submit"), 

      h3("")),

    mainPanel(plotOutput("plot"))

  )
)

# Define server logic required to run sourced function and output ggplot
server <- function(input, output, session) {


  plot_List<-eventReactive(input$Submit, {

    print("ran")
    Helper(input$Partner, input$Budget, input$Month, input$Year)



  })
  #Output the plot
  output$plot<- renderPlot({
    plot = plot_List()
    plot[[1]]

  })



}

# Run the application 
shinyApp(ui = ui, server = server)

Upvotes: 2

Related Questions