[Rd] A where() functions that does what exists() does but return the environment when object lives?

Henrik Bengtsson henrik.bengtsson at ucsf.edu
Wed Oct 14 05:09:34 CEST 2015


Thanks Uwe and thanks Hadley.  I ended up implementing:

## Emulates R internal findVar1mode() function
## https://svn.r-project.org/R/trunk/src/main/envir.c
where <- function(x, where=-1, envir=if (missing(frame)) { if (where <
0) parent.frame(-where) else as.environment(where) } else
sys.frame(frame), frame, mode="any", inherits=TRUE) {
  tt <- 1
  ## Validate arguments
  stopifnot(is.environment(envir))
  stopifnot(is.character(mode), length(mode) == 1L)
  inherits <- as.logical(inherits)
  stopifnot(inherits %in% c(FALSE, TRUE))

  ## Search
  while (!identical(envir, emptyenv())) {
    if (exists(x, envir=envir, mode=mode, inherits=FALSE)) return(envir)
    if (!inherits) return(NULL)
    envir <- parent.env(envir)
  }

  NULL
}

Here where() provides the same arguments as exists() and get().  It
turns out one needs to tweak the default value for 'envir' argument in
order work the same.

One could argue that where() should always return an environment, i.e.
it should return emptyenv() instead of NULL if the object was not
found.  On the other hand, it's easier to test for is.null(env) than
identical(env, emptyenv()).

/Henrik


On Tue, Oct 13, 2015 at 2:44 PM, Hadley Wickham <h.wickham at gmail.com> wrote:
> On Tue, Oct 13, 2015 at 4:43 PM, Hadley Wickham <h.wickham at gmail.com> wrote:
>> Seems easy enough to write yourself:
>>
>> where <- function(x, env = parent.frame()) {
>>     if (identical(env, emptyenv()))
>>         return(NULL)
>>     if (exists(x, envir = env, inherits = FALSE))
>>         return(env)
>>     where(x, parent.env(env))
>> }
>>
>> sample2 <- base::sample
>> where("sample2")
>> #> <environment: 0x1154d3c28>
>
> And that returns a random environment because I ran it with
> reprex::reprex().  In interactive use it will return <environment:
> R_GlobalEnv>
>
> Hadley
>
> --
> http://had.co.nz/



More information about the R-devel mailing list