Skip to content

Help understanding environments

6 messages · Duncan Murdoch, Davis, Brian, Rui Barradas +1 more

#
I have a collection of .RData files that have result objects that I would like to combine.  Specifically, skatCohort objects from the skatMeta package, but I've run into a similar issue with simple data.frames also.

If I run something like

FILES <- list.files(path="/path/to/my/results", pattern=".RData$", full.names=TRUE)
combined <- NULL
  for (FILE in FILES) {
    load(FILE)
    if (!is.null(combined)) {
      combined <- c(combined, res)
    } else {
      combined <- res
    }
  }

I get all my objects combined.  However, if I wrap this into a function I get the following error

c_objects <- function(FILES) {
  combined <- NULL
  for (FILE in FILES) {
    load(FILE)
    if (!is.null(combined)) {
      combined <- c(combined, res)
    } else {
      combined <- res
    }
  }
  return(combined)
}

combined_results <- c_objects(FILES)
Error in eval(expr, envir, enclos) : object 'combined' not found

How should I write this function such that it can find "combined".   I've tried reading the help on envirnaments, and the exisits function but I haven't been able to figure this out.  Are there any other resources to read up on this?

Thanks in advance,

-Brian
#
On 13-06-17 5:02 PM, Davis, Brian wrote:
You are doing something that you aren't showing us:  I don't see any 
calls to eval(), but it's eval() that generated the error.

Calling traceback() after the error might be informative.

Duncan Murdoch
#
In my haste to make a smaller example than my actual code I used 'is.null' instead of 'exists' as is in my code.  Here's a small reproducible example


res <- list(abc=letters, ABC=LETTERS)
save(res, file="results.RData")
res <- list(zyx=rev(letters), ZYX=rev(LETTERS))
save(res, file="results2.RData")

rm(res)
FILES <- c("results.RData", "results2.RData")


c_objects <- function(FILES) {
  for (FILE in FILES) {
    load(FILE)
    if (exists(combined)) {
      combined <- c(combined, res)
    } else {
      combined <- res
    }
  }
  return(combined)
}

combined_results <- c_objects(FILES)


-----Original Message-----
From: Duncan Murdoch [mailto:murdoch.duncan at gmail.com] 
Sent: Monday, June 17, 2013 5:40 PM
To: Davis, Brian
Cc: r-help at r-project.org
Subject: Re: [R] Help understanding environments
On 13-06-17 5:02 PM, Davis, Brian wrote:
You are doing something that you aren't showing us:  I don't see any calls to eval(), but it's eval() that generated the error.

Calling traceback() after the error might be informative.

Duncan Murdoch
#
Hello,

The first argument to exists() must be the name of an object given as a 
character string, as stated in the help page. See ?exists. You have also 
forgot to initialize combined to NULL, this time.
Your function revised would then become


c_objects <- function(FILES) {
   combined <- NULL
   for (FILE in FILES) {
     load(FILE)
     if (exists("combined")) {
       combined <- c(combined, res)
     } else {
       combined <- res
     }
   }
   return(combined)
}


And all works as expected.

Hope this helps,

Rui Barradas


Em 18-06-2013 14:57, Davis, Brian escreveu:
#
Thanks a bunch.  Can't believe I missed that.

-----Original Message-----
From: Rui Barradas [mailto:ruipbarradas at sapo.pt] 
Sent: Tuesday, June 18, 2013 9:57 AM
To: Davis, Brian
Cc: r-help at r-project.org
Subject: Re: [R] Help understanding environments

Hello,

The first argument to exists() must be the name of an object given as a character string, as stated in the help page. See ?exists. You have also forgot to initialize combined to NULL, this time.
Your function revised would then become


c_objects <- function(FILES) {
   combined <- NULL
   for (FILE in FILES) {
     load(FILE)
     if (exists("combined")) {
       combined <- c(combined, res)
     } else {
       combined <- res
     }
   }
   return(combined)
}


And all works as expected.

Hope this helps,

Rui Barradas


Em 18-06-2013 14:57, Davis, Brian escreveu:
#
Since you set
   combined <- NULL
at the top of the function
   exists("combined")
will always return TRUE.  If you initialize 'combined' to NULL,
use is.null(combined) to see if it is still in its virgin state.  If you
don't initialize it to anything then use exists("combined").
In this example you are combining the results with c(), which
essentially ignores NULL arguments so you don't need the
if-else at all if you initialize 'combined' to NULL. 

Bill Dunlap
Spotfire, TIBCO Software
wdunlap tibco.com