[R] with() and within() functions inside lapply() not seeing outside of its environment?

Duncan Murdoch murdoch.duncan at gmail.com
Tue Jan 7 19:19:20 CET 2014


On 07/01/2014 10:35 AM, Pavel N. Krivitsky wrote:
> Hi,
>
> I have a list of sublists, and I want to add and/or remove elements in
> each sublist in accordance with a code snippet. I had thought that an
> elegant way to do that is using a combination of lapply() and within().
> However, the code in the within() call doesn't seem to be able to see
> objects outside of it. For (a simplified) example,
>
> f <- function(x){
>    y <- list(y1=list())
>    y <- lapply(y, within, {z<-x})
>    y
> }
> f(1)
>
> My understanding is that what should happen is that lapply() would
> execute
>
> within(y[["y1"]], {z<-x}),
>
> with 1 substituted for x, within() would notice that z has been assigned
> 1, returning list(z=1), which then gets put into a list as element named
> "y1", so the function should ultimately return
>
> list(y1=list(z=1))
>
> What I get instead (on R 3.0.2 and current trunk, both on Linux) is
>
> Error in eval(expr, envir, enclos) : object 'x' not found
>
> Am I doing something wrong, or is this a bug?
I wouldn't call it a bug, but it's a documented limitation, if you know 
how to read it.  As documented, the expression is evaluated with the 
caller's environment as the parent environment.  But here the caller is 
some code in lapply, not your function f.  x is not found there.

I think this modification works, and is maybe the simplest way to get it 
to work:

f <- function(x){
   y <- list(y1=list())
   mywithin <- function(...) within(...)
   y <- lapply(y, mywithin, {z<-x})
   y
}

The idea here is that the calling frame of f is the environment of 
mywithin(), so x is found there.

Duncan Murdoch

>
>                     Thanks in advance,
>                     Pavel
>
> P.S. If I "hard-code" the value for x, i.e.,
>
> f <- function(){
>    y <- list(y1=list())
>    y <- lapply(y, within, {z<-1})
>    y
> }
> f()
>
> it returns list(y1=list(z=1)) as expected.
>
> P.P.S. with() has the same problem:
>
> f <- function(x){
>    y <- list(y1=list())
>    w <- lapply(y, with, x)
>    w
> }
> f(1)
>
> produces the exact same error as within().
>
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.




More information about the R-help mailing list