0

The code below is a reproducible example. When I comment out the step function, the shiny works well. But when I use step function, the shiny gives the error "object 'tmp.data' not found"

Does anyone have the idea how to make 'tmp.data' visible to the step function? Thank you!

indicators <- mtcars[,c(-1,-6)]
input = list(y='mpg')
tmp.model <- function(){
  tmp.data = cbind(mtcars[input$y], indicators)
  biggest = as.formula(lm(paste(input$y,"~."), tmp.data))
  tmp.model = lm(paste(input$y,"~disp"), tmp.data)
  tmp.model = step(tmp.model, direction="forward", scope=biggest, k=log(nrow(mtcars))) # tmp.data not found
  tmp.model
}
summary(tmp.model())
VicaYang
  • 544
  • 3
  • 17
  • I found some useful discussion in [object-not-found-error-when-passing-model-formula-to-another-function](https://stackoverflow.com/questions/8218196/object-not-found-error-when-passing-model-formula-to-another-function), but the solution post there does not work for my code.. Any advice is appreciated! @Arkun – VicaYang Jun 26 '18 at 05:27
  • This problem is about showing the regression model with shiny. When the input (usually the response variable) change, I want to regress the new model using step and face this scope problem. @MHammer's answer is a useful and clean way to do that. – VicaYang Jul 02 '18 at 06:08

2 Answers2

1

A slightly cleaner version of what I think you're trying to solve:

model_fun <- function(df, resp_var, pred_vars) {
  biggest <- as.formula(paste0(resp_var, " ~ ", paste(pred_vars, collapse = " + ")))
  lm_fit <- lm(biggest, data = df)
  step_fit <- step(lm_fit, direction = "forward", scope = biggest, k = log(nrow(df)))
  step_fit
}
model_fun(mtcars, "mpg", c("cyl", "disp", "hp", "drat", "qsec", "vs", "am", "gear", "carb"))
MHammer
  • 1,274
  • 7
  • 12
  • Yes, it solves my problem! But you might misunderstand my code in some cases. I slightly change it and update it in my answer, thank you! – VicaYang Jul 02 '18 at 06:01
0

Well, I found a very very dirty solution to solve it right now, but I still hope someone can give me a more elegant way to solve this scope problem.

indicators <- mtcars[,c(-1,-6)]
input = list(y='mpg')
tmp.model <- function(){
  # directly write into global environment.....
  .GlobalEnv$tmp.data = cbind(mtcars[input$y], indicators)
  biggest = as.formula(lm(paste(input$y,"~."), tmp.data))
  tmp.model = lm(paste(input$y,"~disp"), tmp.data)
  tmp.model = step(tmp.model, direction="forward", scope=biggest, k=log(nrow(mtcars))) # tmp.data not found
  tmp.model
}
summary(tmp.model())

Update: Thanks to mhammer's answer, now we have a clean solution

model_fun <- function(df, resp_var, must_include, maybe_include) {
  begin <- as.formula(paste0(resp_var, " ~ ", paste(must_include, collapse = " + ")))
  biggest <- as.formula(paste0(resp_var, " ~ ", paste(c(must_include, maybe_include), collapse = " + ")))
  lm_fit <- lm(begin, data = df)
  step_fit <- step(lm_fit, direction = "forward", scope = biggest, k = log(nrow(df)))
  step_fit
}
model_fun(mtcars, "mpg", "disp", c("cyl", "hp", "drat", "qsec", "vs", "am", "gear", "carb"))
VicaYang
  • 544
  • 3
  • 17