Reputation: 1273
I am relatively new to shiny. I created an NBA win-probability model a few weeks ago and have been trying to create a shiny app that will generate the output from my model for which I have created a user-defined function.
In my user interface I want a place to enter numeric input value for "Home Points", "Away Points", and "Time Remaining". Once, values have been entered for these values I want the user to click an action button. After the action button is clicked I simply want the app to display the output from my function in the main panel. However, I am unable to figure out how to get this to work.
Here is my code:
library(shiny)
# Define UI for application that calculates win probability
ui <- fluidPage(
# Application title
titlePanel("Win Probability"),
# Sidebar layout with inputs and output definitions
sidebarLayout(
#sidebar panel for inputs
sidebarPanel(
#Add numeric input for home team points
numericInput(inputId = "home.pts", label = h3("Home Points"), value = 0),
#Add numeric input for away team points
numericInput(inputId = "away.pts", label = h3("Away Points"), value = 0),
#Add numeric input for time remaining in fourth quarter
numericInput(inputId = "time", label = h3("Time Remaining"), value = 0),
#Add action buttion
actionButton("goButton","Apply")),
# Show output
mainPanel(
verbatimTextOutput("win_prob")
)))
win_prob <- function(time, home.pts, away.pts) {
#calculate point difference
diff <- home.pts - away.pts
#Store intercept and betas
intercept <- 0.09564935
b_time <- 0.01087832
b_diff <- 0.5243092
b_interact <- -0.03066952
#calculate and store logit
logit <- intercept + (time*b_time) + (diff*b_diff) +
((time*diff)*b_interact)
#function to change logit to probability
logit2prob <- function(logit) {
odds <- exp(logit)
prob <- odds/(1+odds)
}
#Store probability
prob <- logit2prob(logit)
prob
}
# Define server to return win probability
server <- function(input, output) {
#Store reactive values
home.pts <- reactive({input$home.pts})
away.pts <- reactive({input$away.pts})
time <- reactive({input$time})
output$win_prob <- renderPrint({win_prob(reactive({input$home.pts}),
reactive({input$away.pts}), reactive({input$time}))})
}
# Run the application
shinyApp(ui = ui, server = server)
If someone can please help me I would greatly appreciate it!
Thank you!
Upvotes: 2
Views: 2126
Reputation: 13125
Using reactivity
server <- function(input, output) {
#Store reactive values
home.pts <- reactive({input$home.pts})
away.pts <- reactive({input$away.pts})
time <- reactive({input$time})
output$win_prob <- renderPrint({win_prob(home.pts(), away.pts(), time())})
}
Using ObserveEvent
server <- function(input, output) {
data <- reactiveValues()
observeEvent(input$goButton,{
data$home.pts <- input$home.pts
data$away.pts <- input$away.pts
data$time <- input$time
})
output$win_prob <- renderPrint({
req(data$home.pts) #to delay displaying result until user press Apply
win_prob(data$home.pts,data$away.pts, data$time)})
}
Now you can see the deference between the two approaches
Upvotes: 1
Reputation: 2995
Well you don't need to store all your inputs in reactive values. They already update themselves. When you have an actionButton
, the best way to trigger an event from the click on the button is to use observeEvent
. If I understood well, I would rewrite your server function like this:
# Define server to return win probability
server <- function(input, output) {
observeEvent(input$goButton, {
output$win_prob <- renderPrint({
win_prob(input$home.pts,
input$away.pts,
input$time)
})
})
}
Upvotes: 1