1

I am trying to build a Shiny app that allows the user to predict (lm) an outcome based being able to select the input feature (dataset column) from a dropdown menu.

The problem is I can't find a way to set the input variable into the prediction model which will switch between input variables based on the drop down menu.

Image 1: where SNR is used from dropdown

Image 2: where different variable (RSRP) is used

I had issues a first being able to get the slider scale (left side) and the x-axis in my plot to change based on the selection from the dropdown window, however I overcame this with use of conditionalPanel and setting the condition to the required input.indepvar Whilst this will work: predict(fit, newdata = data.frame(SNR = varInput))
This will not selectVar<-input$indepvar
predict(fit, newdata = data.frame(selectVar = varInput)) Even though printing out selectVar gives SNR as a result (I have this rendered as a test output a the end). I basically want to somehow replace the SNR value with whatever is selected from the dropdown menu (input$indepvar). The data used is from the pedestrian folder in this dataset: http://www.cs.ucc.ie/~dr11/4G_Dataset/LTE_Dataset.zip

## Only run this example in interactive R sessions
if (interactive()) {
        shinyApp(
                ui <- fluidPage(
                        titlePanel("Regression Model (Dataset: pedestrian)"),
                        sidebarLayout(
                                sidebarPanel(
                                        selectInput("outcome", label = h3("Outcome"),
                                                    choices = list("DL_bitrate" = "DL_bitrate",
                                                                   "UL_bitrate" = "UL_bitrate",
                                                                   "RSSI" = "RSSI",
                                                                   "SNR" = "SNR",
                                                                   "RSRP" = "RSRP",
                                                                   "CQI" = "CQI"), selected = 1),
                                        
                                        selectInput("indepvar", label = h3("Explanatory variable"),
                                                    choices = list("SNR" = "SNR",
                                                                   "RSRP" = "RSRP",
                                                                   "RSRQ" = "RSRQ",
                                                                   "CQI" = "CQI",
                                                                   "ServingCell_Distance" = "ServingCell_Distance"), selected = 1),
                                        conditionalPanel(
                                                condition = "input.indepvar == 'SNR'",
                                                sliderInput("sliderIndVar",
                                                            label = "SNR Range:",
                                                            min = -10, max = 30, 5)
                                        ),
                                        conditionalPanel(
                                                condition = "input.indepvar == 'RSRP'",
                                                sliderInput("sliderIndVar",                # Plan on updating this but was working with SNR to start with 
                                                            label = "RSRP Range:",
                                                            min = -115, max = -65, 100)
                                        ),
                                        conditionalPanel(
                                                condition = "input.indepvar == 'RSRQ'",
                                                sliderInput("sliderIndVar",                # Plan on updating this but was working with SNR to start with 
                                                            label = "RSRQ Range:",
                                                            min = -18, max =-8, -12)
                                        ),
                                        conditionalPanel(
                                                condition = "input.indepvar == 'CQI'",
                                                sliderInput("sliderIndVar",                # Plan on updating this but was working with SNR to start with 
                                                            label = "CQI Range:",
                                                            min = 0, max = 15, 8)
                                        ),
                                        conditionalPanel(
                                                condition = "input.indepvar == 'ServingCell_Distance'",
                                                sliderInput("sliderIndVar",                # Plan on updating this but was working with SNR to start with 
                                                            label = "Serving Cell Distance:",
                                                            min = 150, max = 75000, 1000)
                                        )
                                        
                                        
                                ),
                                
                                mainPanel(
                                        
                                        tabsetPanel(type = "tabs",
                                                    
                                                    tabPanel("Scatterplot", plotOutput("scatterplot"),
                                                             h3("Slider Value:"), 
                                                             textOutput("text"),      # This show the select input from the slider for test purpose
                                                             h3("Predicted Value:"),  # This show the resultant prediction for test purpose
                                                             textOutput("pred1"),     # Works ok for SNR - as I've hard coded SNR in server model1pred  
                                                             h3("Select variable:"),  # This show the variable selected from the drop down 
                                                             textOutput("var1")),     # I want to use this variable as input to model1pred
                                                    tabPanel("Distribution", # Plots of distributions
                                                             fluidRow(
                                                                     column(6, plotOutput("distribution1")),
                                                                     column(6, plotOutput("distribution2")))
                                                    ),
                                                    tabPanel("Model Summary", verbatimTextOutput("summary")), # Regression output
                                                    tabPanel("Data", DT::dataTableOutput('tbl')) # Data as datatable
                                                    
                                        )
                                )
                        )), 
                server <- function(input, output) {
                        
                        # Regression output
                        output$summary <- renderPrint({
                                fit <- lm(pedestrian[,input$outcome] ~ pedestrian[,input$indepvar])
                                names(fit$coefficients) <- c("Intercept", input$var2)
                                summary(fit)
                        })
                        
                        # Prediction value
                        model1pred <- reactive({ 
                                varInput <- input$sliderIndVar
                                # selectVar<-input$indepvar                             # Was trying to use something like thi to replace SNR in prediction!!
                                
                                predict(fit, newdata = data.frame(SNR = varInput))      # I want to replace SNR with which variable is selected from the 
                                # selectInput("indepvar" drop menu. 
                                #                predict(fit, newdata = data.frame(selectVar = varInput))      # This doesn't work for example 
                        })
                        
                        # Data output
                        output$tbl = DT::renderDataTable({
                                DT::datatable(pedestrian, options = list(lengthChange = FALSE))
                        })
                        
                        
                        # Scatterplot output
                        output$scatterplot <- renderPlot({
                                varInput <- input$sliderIndVar                             # UPDATE HERE to be flexible with drop down menu!! 
                                plot(pedestrian[,input$indepvar], pedestrian[,input$outcome], main="Scatterplot",
                                     xlab=input$indepvar, ylab=input$outcome, pch=19)
                                abline(lm(pedestrian[,input$outcome] ~ pedestrian[,input$indepvar]), col="red")
                                lines(lowess(pedestrian[,input$indepvar],pedestrian[,input$outcome]), col="blue")
                                points(varInput, model1pred(), col = "red", pch = 16, cex = 2) 
                        }, height=400)
                        
                        
                        # Histogram output var 1
                        output$distribution1 <- renderPlot({
                                hist(pedestrian[,input$outcome], main="", xlab=input$outcome)
                        }, height=300, width=300)
                        
                        # Histogram output var 2
                        output$distribution2 <- renderPlot({
                                hist(pedestrian[,input$indepvar], main="", xlab=input$indepvar)
                        }, height=300, width=300)
                        
                        # Slider input & Prediction
                        output$text <- renderText({input$sliderIndVar}) 
                        # UPDATE HERE!!
                        output$pred1 <- renderText(model1pred())        # I want to also update the prediction based on the selection from the drop down menu
                        output$var1 <- renderText(input$indepvar)       # I can get this to update based on the 
                        
                        
                        
                }
        )
}

Prediction value does not update when I select anything other than SNR.

As a result my predicted point on the chart also does not update. Everything else works (axis scales, slider scales based on the selected input variable). Any ideas would be much appreciated.

Community
  • 1
  • 1
Tsunamimor
  • 21
  • 1
  • 2

1 Answers1

3

If I'm not mistaken, you can't use the same inputId for all the sliders. Only one of them will be available as a value. You could confirm this in a print(input$sliderIndVar) within an observer in the server to make sure.

I would suggest giving a different inputId for each slider. Like sliderIndVarRSRP, sliderIndVarSNR and so on, and then call them in the server with input[[paste0("sliderIndVar", input$indepvar)]]. This should specify which slider you are calling.

EDIT1: As for the name of the variable in the data.frame.

Since you want to define the name of the variable in the newdata as input$indepvar, I can only think of changing the name after the data.frame is created, like this:

varInput <- input$sliderIndVarWHATEVER
newdataInput <- data.frame(varInput)
colnames(newdataInput) <- input$indepvar
predict(fit, newdata = newdataInput)
Edgar
  • 256
  • 2
  • 12
  • Hi Edgar, thank for your guidance. I have used the paste functionality and taken care of the `varInput` which now is taking into consideration the slider that is selected (I also updated their individual names as you suggested). – Tsunamimor Feb 18 '19 at 18:25
  • However, I am still having difficulty replacing the feature selection component in the `data.frame` selection with a working variable. I keep getting an error telling me: object 'SNR' not found which I am guessing the this result SNR is being treated as a variable itself rather than the column name in question being selected. I tried `fitInput <- as.character(input$indepvar)` as input to the `predict(fit, newdata = data.frame(fitInput = varInput))` but that doesn't work. The original `predict(fit, newdata = data.frame(SNR = varInput))` and I tried replacing the SNR text with `input$indepvar ` – Tsunamimor Feb 18 '19 at 18:28
  • Hi, Tsunamimor. Yeah, I didn't think of that. The parameters for `data.frame` are `tag = value`, so whatever you put as tag will be the name of the column. Since you want to use a reactive value as a name, I can only thinking of changing the name after you create the dataset, like this: `newdataInput <- data.frame(varInput)` and then `colnames(newdataInput) <- input$indepvar`. This would create a data.frame with colname `input$indepvar` and value `input$sliderIndVarWHATEVER` in your case. I'll update this in the answer. – Edgar Feb 19 '19 at 12:21
  • Another thing I don't understand why is working (if it is) is the `fit` variable. I believe it is being created during `output$summary`? It doesn't look reactive, thogh. I would suggest creating a `fit <- reactive({})` in the server for the lm model. If it is working, nevermind this. – Edgar Feb 19 '19 at 12:22
  • 1
    Using `newdataInput`worked very nicely! BTW you were right about the `fit` variable not being reactive. I was testing the 'fit <- lm()' earlier and forgot to remove the result afterwards so my prediction was referencing that model. – Tsunamimor Feb 20 '19 at 20:22