Pavel N. Krivitsky
2014-Jan-07 15:35 UTC
[R] with() and within() functions inside lapply() not seeing outside of its environment?
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? 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().
Duncan Murdoch
2014-Jan-07 18:19 UTC
[R] with() and within() functions inside lapply() not seeing outside of its environment?
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.