Search code examples
rscopingmass-package

R Passing linear model to another function inside a function


I am trying to find the optimal "lambda" parameter for the Box-Cox transformation.

I am using the implementation from the MASS package, so I only need to create the model and extract the lambda.

Here is the code for the function:

library(MASS)

find_lambda <- function(x) {
  # Function to find the best lambda for the Box-Cox transform

  my_tmp <- data.frame(x = x) # Create a temporary data frame, to use it with the lm
  str(my_tmp) # Gives the expected output

  the_lm <- lm(x ~ 1, data = my_tmp) # Creates the linear model, no error here
  print(summary(the_lm)) # Prints the summary, as expected

  out <- boxcox(the_lm, plotit=FALSE) # Gives the error

  best_lambda <- out$x[which.max(out$y)] # Extracting the best fitting lambda
  return(best_lambda)
}

find_lambda(runif(100))

It gives the following error:

Error in is.data.frame(data) : object 'my_tmp' not found 

The interesting thing is that the very same code is working outside the function. In other words, for some reason, the boxcox function from the MASS package is looking for the variable in the global environment.

I don't really understand, what exactly is going on... Do you have any ideas?

P.S. I do not provide a software/hardware specification, since this error was sucessfully replicated on a number of my friends' laptops.

P.P.S. I have found the way to solve the initial problem in the forecast package, but I still would like to know, why this code is not working.


Solution

  • boxcox cannot find your data. This maybe because of some scoping issue.
    You can feed data in to boxcox function.

    find_lambda <- function(x) {
      # Function to find the best lambda for the Box-Cox transform
    
      my_tmp <- data.frame(x = x) # Create a temporary data frame, to use it with the lm
      str(my_tmp) # Gives the expected output
    
      the_lm <- lm(x ~ 1, data = my_tmp) # Creates the linear model, no error here
      print(summary(the_lm)) # Prints the summary, as expected
    
      out <- boxcox(the_lm, plotit=FALSE, data = my_tmp) # feed data in here
    
      best_lambda <- out$x[which.max(out$y)] # Extracting the best fitting lambda
      return(best_lambda)
    }
    
    find_lambda(runif(100))