Ferroao Ferroao - 3 months ago 65
R Question

how to predict based on linear models with reactive variables in shiny

I would like to kindly request some way to predict with lm (linear model) in R, that accepts reactive variables.

If you have a linear model "lm" with y and x, "predict" can be done for new data giving new values for x. I would like to do that for reactive y and x in a shiny app
In the following working example, I created somehow (arbitrarily, just to make it work) reactive y and x values for the lm, and also a input to give a changing new value (to be used as new x).
The objective is to correctly get the predicted y for the new (input) x considering y(), x() .

library(shiny)
ui <- fluidPage (

sidebarLayout(
sidebarPanel
(
numericInput('variable1', 'new x', 0.1, min = 0, max = 100, step = 0.1)
),
mainPanel (plotOutput('plot1') )
)
)

server <- function(input, output){



## Initial data and linear regression that should be reactive,
# the dependency on input$variable1<1 is just an example to work with a lm based on reactive data.
y<- reactive (
if (input$variable1<1)
{
y <- c(3.1, 3.25, 3.5, 4, 3.5, 5, 5.5)
}
else
y <- c(.1, .25, .5, 1, 1.5, 2, 2.5)
)

x<- reactive (
if (input$variable1>=1)
{
x <- c(.1, .332, .631, .972, 1.201, 1.584, 1.912)
}
else
x <- c(.1, .3, .631, .972, 2.201, 2.584, 2.912)
)

results <- reactive({
r <- data.frame(y(),x())
})

lmod <- reactive ({
mod1 <- lm(y()~ x(), data = results()
)
})

output$plot1 <- renderPlot({
plot(x(),y())
abline(lmod())

#overwrite problem, we have a new x, which is also x() as the previous
x <-reactive ({ x <- input$variable1 })
newdata <- reactive ({ data.frame(x() ) } )

#problem here, predict does not work with reactive x()
newdata.pred <- reactive ({ predict(lmod(),newdata(),level=1)
})

#problem is visible here, newdata.pred is not the predicted value for the input (new x)
segments(input$variable1, 0, input$variable1, newdata.pred(), col = "red")
} )

} # end server
shinyApp(ui, server)

Answer

It's better when using lm() and predict to have a properly named data.frame and use a proper formula. If you change these parts

results <- reactive({ 
  r <- data.frame(y=y(),x=x())
})

lmod <- reactive ({ 
  mod1 <- lm(y~x, data = results() )
 })

and

newdata <- reactive ({  data.frame(x=x() ) } )

I think you will get the behavior you want. Now both the model fitting data.frame and the predicting data.frame have a column named x and the formula used in the lm() clearly lists x as the variable used to predict y

Comments