rfunctionlogistf

error: 'object not found' in nested functions


I was writing a function using the logistf::logistf and logistf::forward function. I will give here a minimum working example using sex2 from the logistf package.

data(sex2)
fwSel <- function(datamod) {
  fitnull <- logistf(case ~ 1, data = datamod, pl = FALSE) 
  fw <- forward(fitnull)
  return(fw)
}
fwSel(sex2)

I get the following output:

Step 0 : starting model

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

Has anybody an explanation for that?


Solution

  • This is a typical error which you can get in R. It has been asked again and unfortunately it happens according to how different functions work in different environments and how functions try to find data according to the use of parent.env or parent.frame. It might be one of the two problems:

    data(sex2)
    datamod <- sex2
    fwSel <- function(datamod) {
        fitnull <- logistf(case ~ 1, data = datamod, pl = FALSE) 
        fw <- forward(fitnull)
        return(fw)
    }
    fwSel(sex2)
    

    This will definitely work because the global environment will be searched anyway.

    I find this link as an excellent way of finding out how the parent.env is different to parent.frame and how using those two inside functions can cause problems like the one you are facing.

    I made a new example based on the functions in the link that demonstrates your problem exactly:

    f = function() {
      print(c(f=environment(), defined_in=parent.env(environment()),  
        called_from=parent.frame()))
    
      #search for mydata in calling environment
      try(print(get('mydata',env=parent.frame())))  
    
      #search for mydata in parent evnironment
      try(print(get('mydata',env=parent.env(environment())))) 
      }
    
    g = function() {
      mydata <- c(1,2,3)
      print(c(g=environment(), f()))
      }   
    
    > g()
    $f
    <environment: 0x0000000030868df8>
    
    $defined_in
    <environment: R_GlobalEnv>
    
    $called_from
    <environment: 0x000000003086a360>
    
    #the first get works perfect
    [1] 1 2 3       
    
    #the second produces an error
    Error in get("mydata", env = parent.env(environment())) : 
      object 'mydata' not found
    
    $g
    <environment: 0x000000003086a360>
    

    As you can see above using get with the calling environment works whereas using get with the parent environment fails and produces an error. This is what (probably) happens in your functions too.