【问题标题】:How to predict lm model based on variable selected from a drop down in Shiny App?如何根据从 Shiny App 中的下拉列表中选择的变量来预测 lm 模型?
【发布时间】:2019-07-11 04:58:39
【问题描述】:

我正在尝试构建一个闪亮的应用程序,允许用户基于能够从下拉菜单中选择输入特征(数据集列)来预测(lm)结果。

问题是我找不到将输入变量设置到预测模型中的方法,该模型将根据下拉菜单在输入变量之间切换。

Image 1: where SNR is used from dropdown

Image 2: where different variable (RSRP) is used

我遇到了问题,首先能够根据下拉窗口中的选择来更改绘图中的滑块比例(左侧)和 x 轴,但是我通过使用 conditionalPanel 并设置条件克服了这个问题到所需的 input.indepvar 虽然这会起作用: 预测(拟合,newdata = data.frame(SNR = varInput))
这不会 selectVar 预测(拟合,newdata = data.frame(selectVar = varInput)) 即使打印出 selectVar 结果会给出 SNR(我将其呈现为最后的测试输出)。 我基本上想以某种方式将 SNR 值替换为从下拉菜单中选择的任何值 (input$indepvar)。 使用的数据来自该数据集中的行人文件夹: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 
                        
                        
                        
                }
        )
}

当我选择 SNR 以外的任何内容时,预测值不会更新。

因此,我在图表上的预测点也没有更新。 其他一切都有效(轴刻度、基于所选输入变量的滑块刻度)。 任何想法将不胜感激。

【问题讨论】:

    标签: r drop-down-menu shiny user-input prediction


    【解决方案1】:

    如果我没记错的话,您不能对所有滑块使用相同的 inputId。其中只有一个可用作值。您可以在服务器的观察者中通过print(input$sliderIndVar) 确认这一点以确保。

    我建议为每个滑块提供不同的 inputId。比如sliderIndVarRSRPsliderIndVarSNR等等,然后在服务器中用input[[paste0("sliderIndVar", input$indepvar)]]调用它们。这应该指定您正在调用的滑块。

    EDIT1:至于data.frame中的变量名。

    既然要在newdata中定义变量的名字为input$indepvar,我只能想着在data.frame创建后改名字,像这样:

    varInput <- input$sliderIndVarWHATEVER
    newdataInput <- data.frame(varInput)
    colnames(newdataInput) <- input$indepvar
    predict(fit, newdata = newdataInput)
    

    【讨论】:

    • 您好 Edgar,感谢您的指导。我已经使用了粘贴功能并处理了varInput,它现在正在考虑选择的滑块(我还按照你的建议更新了它们的个人名称)。
    • 但是,我仍然难以用工作变量替换 data.frame 选择中的特征选择组件。我不断收到一个错误告诉我:找不到对象“SNR”,我猜这个结果 SNR 被视为变量本身,而不是选择了有问题的列名。我尝试将fitInput &lt;- as.character(input$indepvar) 作为predict(fit, newdata = data.frame(fitInput = varInput)) 的输入,但这不起作用。原来的predict(fit, newdata = data.frame(SNR = varInput)),我尝试用input$indepvar 替换SNR文本
    • 嗨,海啸。是的,我没想到。 data.frame 的参数是tag = value,所以无论你作为标签放置什么,都将是列的名称。由于您想使用反应值作为名称,我只能在您创建数据集后考虑更改名称,如下所示:newdataInput &lt;- data.frame(varInput) 然后colnames(newdataInput) &lt;- input$indepvar。在您的情况下,这将创建一个带有 colname input$indepvar 和 value input$sliderIndVarWHATEVER 的 data.frame。我会在答案中更新这个。
    • 另一件事我不明白为什么工作(如果是的话)是fit 变量。我相信它是在output$summary 期间创建的?它看起来没有反应,虽然。我建议在服务器中为 lm 模型创建一个fit &lt;- reactive({})。如果它有效,请不要介意。
    • 使用newdataInput工作得非常好!顺便说一句,您对 fit 变量没有反应是正确的。我之前正在测试“fit
    猜你喜欢
    • 1970-01-01
    • 2020-11-13
    • 2015-06-22
    • 2017-01-11
    • 1970-01-01
    • 2014-05-12
    • 2014-07-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多