Reputation: 113
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
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