Search code examples
rshinyselectinput

Use selectInput in shiny to plot different regression lines


I am practicing some shiny app creating using the baeskel data in the alr4 package. My goal is to create a selectInput dropdown menu so the user can select which regression line to plot. I am uncertain how to arrange the code in the server part. So far, for one plotted line I have created this:

library(alr4)
data("baeskel")
ui <- fluidPage(
  sidebarLayout(position="left",
                sidebarPanel("sidebarPanel", width=4),
                mainPanel(
                  tabsetPanel(type = "tabs",
                              tabPanel("baeskal Data", tableOutput("table")),
                              tabPanel("Polynomial Regression", plotOutput("polyplot"))
                              )
                          )
                )
  )
  
server <- function(input, output){
  output$table <- renderTable({
    baeskel
  })
  
  x <- baeskel$Sulfur
  y <- baeskel$Tension
  output$polyplot <- renderPlot({
    plot(y~x, pch = 16,xlab="Sulfur",ylab="Tension",
         main = "Observed Surface Tension of\nLiquid Copper with Varying Sulfur Amount")
    linear_mod = lm(y~x, data = baeskel)
    linear_pred = predict(linear_mod)
    lines(baeskel$Sulfur, linear_pred,lwd=2,col="blue")
    })
  
}

shinyApp(ui = ui, server = server)

It works really well. My next goal is to add another regression line as follows:

quadratic_mod <- lm(Tension ~ poly(Sulfur, 2), data = baeskel)
quadratic_pred <- predict(quadratic_mod)
lines(baeskel$Sulfur, quadratic_pred, lwd = 2, col = "green")

However I would like to use the selectInput function as follows (not pictured in the sidebarlayout yet):

selectInput(inputId =  , "Choose Regression Line:", c("Linear", "Quadratic"))

I do not know how to choose the inputId so it can gather the information from each regression line.


Solution

  • Here is a working example that allows for different prediction models to be plotted in shiny.

    In your ui, add the selectInput to choose the type of regression line.

    In server, you can add an if statement to check this input, and determine which model to build from the data.

    The appropriate predictions from the model and lines will be drawn accordingly.

    library(alr4)
    library(shiny)
    
    data("baeskel")
    
    ui <- fluidPage(
      sidebarLayout(position="left",
                    sidebarPanel(
                      "sidebarPanel", width=4,
                      selectInput(inputId = "reg_line", "Choose Regression Line:", c("Linear", "Quadratic"))),
                    mainPanel(
                      tabsetPanel(type = "tabs",
                                  tabPanel("baeskal Data", tableOutput("table")),
                                  tabPanel("Polynomial Regression", plotOutput("polyplot"))
                      )
                    )
      )
    )
    
    server <- function(input, output){
      output$table <- renderTable({
        baeskel
      })
      
      output$polyplot <- renderPlot({
        plot(Tension ~ Sulfur, data = baeskel, pch = 16, xlab="Sulfur", ylab="Tension",
             main = "Observed Surface Tension of\nLiquid Copper with Varying Sulfur Amount")
        
        if(input$reg_line == "Linear") {
          baeskel_mod = lm(Tension ~ Sulfur, data = baeskel)
        } else {
          baeskel_mod = lm(Tension ~ poly(Sulfur, 2), data = baeskel)
        }
        
        baeskel_pred = predict(baeskel_mod)
        lines(baeskel$Sulfur, baeskel_pred, lwd=2, col="blue")
      })
      
    }
    
    shinyApp(ui = ui, server = server)