Search code examples
rloess

Invalid type (closure) for a variable that is not a function


loess.smooth <- function(dat) {
  dat <- dat[complete.cases(dat),]

  ## response
  vars <- colnames(dat)
  ## covariate
  id <- 1:nrow(dat)
  ## define a loess filter function (fitting loess regression line)
  loess.filter <- function (x, span) loess(formula = paste(x, "id", sep = "~"),
                                           data = dat,
                                           degree = 1,
                                           span = span)$fitted 
  ## apply filter column-by-column
  new.dat <- as.data.frame(lapply(vars, loess.filter, span = 0.75),
                           col.names = colnames(dat))
}

When I try to apply loess.smooth to a dataframe, I get the error:

 Error in model.frame.default(formula = paste(x, "id", sep = "~"), data = dat) : 
  invalid type (closure) for variable 'id' 

I don't understand why this is a problem since id is not a function, which is implied by the error. When I run through these lines of code outside of the function, it works perfectly fine and does exactly what I want it to do.


Solution

  • It is a scoping issue involving passing a vector of strings to the loess function instead of passing a vector of formulas. The problem is that the environment returns NULL for the former, so loess doesn't know where to find it. If you wrap the formula in as.formula it works. This variable will be assigned the local environment inside the function call by default.

    As to the cryptic error, it happens when you name a variable the same name of a given function from another package that is loaded, since if a function doesn't find a variable in the local environment, it will scope in the loaded packages for the function. In my case, the id function was loaded by the dplyr library.