Re: [R] with vs. attach

2016-05-09 Thread Hadley Wickham
On Mon, May 9, 2016 at 7:12 AM, peter dalgaard  wrote:
>
> On 09 May 2016, at 02:46 , Bert Gunter  wrote:
>
>> ... To be clear, Hadley or anyone else should also feel free to set me
>> straight, preferably publicly, but privately if you prefer.
>
> Not really to "set anyone straight", but there are some subtleties with mode 
> call objects versus expression objects and formulas to be aware of.
>
> E.g.,
>
>> a <- 2
>> do.call("print", list(a*pi))
> [1] 6.283185
>> do.call("print", list(quote(a*pi)))
> [1] 6.283185
>> do.call("print", list(expression(a*pi)))
> expression(a * pi)
>> do.call("print", list(~a*pi))
> ~a * pi
>
> Thing is, if you insert a call object into a parse tree, nothing is there to 
> preserve its nature as an unevaluated expression. Similarly, in
>
>> call("print", quote(a*pi))
> print(a * pi)
>
> the result is identical to quote(print(a * pi)), so when evaluated, quoting 
> is not seen by print().
>
> As far as I understand, this is also the reason that for math in ggplot, you 
> may need as.expression(bquote()).
>
> In general, I think that a number of things in R had been more cleanly 
> implemented using formulas/expression objects than using substitution and 
> lazy evaluation, notably subset and offset arguments in lm/glm. It would have 
> been so much cleaner to have
>
> lm(math ~ age, data = foo, subset = ~ sex=="1")
>
> than the current situation where lm internally chops its own head off and 
> substitutes with model.frame, then evaluates the call to model.frame() which 
> in turn does eval(substitute(subset), data, env). Of course, at the time, ~ 
> was intended specifically for Wilkinson Rogers type formulas; "abusing" it 
> for other kinds of expressions is something of an afterthought.

Yeah, to my mind, the cool thing about formulas is that they provide a
concise way to capture an environment and an expression, and then
Wilkinson Rogers are just a special case.

It's obvious impossible to go back and change how lm() etc works now,
but I'm reasonably confident that lazyeval provides a strong
foundation going forward. The quasiquotation stuff is particularly
important - and unquote-splice makes it possible to do things that are
impossible with bquote().  (Of course, unquote-splice could be added
to bquote(), but I think you'll still run into issues with
environments)

Hadley


-- 
http://hadley.nz

__
R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see
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.


Re: [R] with vs. attach

2016-05-09 Thread Hadley Wickham
On Sun, May 8, 2016 at 7:28 PM, Bert Gunter  wrote:
> Jeff:
>
> That's easy to do already with substitute(), since you can pass around
> an unevaluated expression (a parse tree) however you like. As I read
> it, (admittedly quickly) what it's main feature is that it allows you
> more control over the environment in which the expression is finally
> evaluated -- as well as permitting nested expression evaluation fairly
> easily.
>
> But maybe we're saying the same thing ...  IMHO I think Hadley has
> gone overboard here, worrying about rarely important issues, as you
> seem to be intimating also.

These are absolutely critical issues that crop up as soon as other
people want to write functions that use your functions that use NSE.

Hadley

-- 
http://hadley.nz

__
R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see
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.


Re: [R] with vs. attach

2016-05-09 Thread peter dalgaard

On 09 May 2016, at 02:46 , Bert Gunter  wrote:

> ... To be clear, Hadley or anyone else should also feel free to set me
> straight, preferably publicly, but privately if you prefer.

Not really to "set anyone straight", but there are some subtleties with mode 
call objects versus expression objects and formulas to be aware of. 

E.g.,

> a <- 2
> do.call("print", list(a*pi))
[1] 6.283185
> do.call("print", list(quote(a*pi)))
[1] 6.283185
> do.call("print", list(expression(a*pi)))
expression(a * pi)
> do.call("print", list(~a*pi))
~a * pi

Thing is, if you insert a call object into a parse tree, nothing is there to 
preserve its nature as an unevaluated expression. Similarly, in

> call("print", quote(a*pi))
print(a * pi)

the result is identical to quote(print(a * pi)), so when evaluated, quoting is 
not seen by print().

As far as I understand, this is also the reason that for math in ggplot, you 
may need as.expression(bquote()).

In general, I think that a number of things in R had been more cleanly 
implemented using formulas/expression objects than using substitution and lazy 
evaluation, notably subset and offset arguments in lm/glm. It would have been 
so much cleaner to have

lm(math ~ age, data = foo, subset = ~ sex=="1")

than the current situation where lm internally chops its own head off and 
substitutes with model.frame, then evaluates the call to model.frame() which in 
turn does eval(substitute(subset), data, env). Of course, at the time, ~ was 
intended specifically for Wilkinson Rogers type formulas; "abusing" it for 
other kinds of expressions is something of an afterthought. 

-pd

> 
> Cheers,
> Bert
> Bert Gunter
> 
> "The trouble with having an open mind is that people keep coming along
> and sticking things into it."
> -- Opus (aka Berkeley Breathed in his "Bloom County" comic strip )
> 
> 
> On Sun, May 8, 2016 at 5:28 PM, Bert Gunter  wrote:
>> Jeff:
>> 
>> That's easy to do already with substitute(), since you can pass around
>> an unevaluated expression (a parse tree) however you like. As I read
>> it, (admittedly quickly) what it's main feature is that it allows you
>> more control over the environment in which the expression is finally
>> evaluated -- as well as permitting nested expression evaluation fairly
>> easily.
>> 
>> But maybe we're saying the same thing ...  IMHO I think Hadley has
>> gone overboard here, worrying about rarely important issues, as you
>> seem to be intimating also.
>> 
>> Feel free to set me straight... or ignore.
>> 
>> Cheers,
>> Bert
>> Bert Gunter
>> 
>> "The trouble with having an open mind is that people keep coming along
>> and sticking things into it."
>> -- Opus (aka Berkeley Breathed in his "Bloom County" comic strip )
>> 
>> 
>> On Sun, May 8, 2016 at 4:02 PM, Jeff Newmiller  
>> wrote:
>>> The lazyeval package addresses the problem of how to delay evaluation even 
>>> when the function you want to do the evaluation in is buried two or more 
>>> function calls below where the original call was made. If you are not 
>>> building nested function calls with delayed evaluation then you probably 
>>> don't need that package.
>>> --
>>> Sent from my phone. Please excuse my brevity.
>>> 
>>> On May 8, 2016 3:30:16 PM PDT, Spencer Graves 
>>>  wrote:
 Hi, Hadley et al.:
 
 
  Hadley's link requires his development version of "lazyeval",
 which can be obtained as follows:
 
 
 library(devtools)
 install_github("hadley/lazyeval")
 
 
  Hadley's link describes real problems with elegant solutions.
 
 
  However, David's solution solved my immediate problem, and it's
 not immediately obvious to me how his "expr_text" function (or other
 functions in "lazyevel") to produce a better solution.
 
 
  Thanks again to David, Peter and Hadley for their replies.
 
 
  Spencer Graves
 
 
 On 5/6/2016 5:08 PM, Hadley Wickham wrote:
> You may want to read http://rpubs.com/hadley/157957, which captures
 my
> latest thinking (and tooling) around this problem. Feedback is much
> appreciated.
> 
> Hadley
> 
> On Fri, May 6, 2016 at 2:14 PM, David Winsemius
  wrote:
>>> On May 6, 2016, at 5:47 AM, Spencer Graves
  wrote:
>>> 
>>> 
>>> 
>>> On 5/6/2016 6:46 AM, peter dalgaard wrote:
 On 06 May 2016, at 02:43 , David Winsemius
  wrote:
 
>> On May 5, 2016, at 5:12 PM, Spencer Graves
  wrote:
>> 
>> I want a function to evaluate one argument
>> in the environment of a data.frame supplied
>> as another argument.  "attach" works for
>> this, but "with" does not.  Is there a way

Re: [R] with vs. attach

2016-05-08 Thread Bert Gunter
... To be clear, Hadley or anyone else should also feel free to set me
straight, preferably publicly, but privately if you prefer.

Cheers,
Bert
Bert Gunter

"The trouble with having an open mind is that people keep coming along
and sticking things into it."
-- Opus (aka Berkeley Breathed in his "Bloom County" comic strip )


On Sun, May 8, 2016 at 5:28 PM, Bert Gunter  wrote:
> Jeff:
>
> That's easy to do already with substitute(), since you can pass around
> an unevaluated expression (a parse tree) however you like. As I read
> it, (admittedly quickly) what it's main feature is that it allows you
> more control over the environment in which the expression is finally
> evaluated -- as well as permitting nested expression evaluation fairly
> easily.
>
> But maybe we're saying the same thing ...  IMHO I think Hadley has
> gone overboard here, worrying about rarely important issues, as you
> seem to be intimating also.
>
> Feel free to set me straight... or ignore.
>
> Cheers,
> Bert
> Bert Gunter
>
> "The trouble with having an open mind is that people keep coming along
> and sticking things into it."
> -- Opus (aka Berkeley Breathed in his "Bloom County" comic strip )
>
>
> On Sun, May 8, 2016 at 4:02 PM, Jeff Newmiller  
> wrote:
>> The lazyeval package addresses the problem of how to delay evaluation even 
>> when the function you want to do the evaluation in is buried two or more 
>> function calls below where the original call was made. If you are not 
>> building nested function calls with delayed evaluation then you probably 
>> don't need that package.
>> --
>> Sent from my phone. Please excuse my brevity.
>>
>> On May 8, 2016 3:30:16 PM PDT, Spencer Graves 
>>  wrote:
>>>Hi, Hadley et al.:
>>>
>>>
>>>   Hadley's link requires his development version of "lazyeval",
>>>which can be obtained as follows:
>>>
>>>
>>>library(devtools)
>>>install_github("hadley/lazyeval")
>>>
>>>
>>>   Hadley's link describes real problems with elegant solutions.
>>>
>>>
>>>   However, David's solution solved my immediate problem, and it's
>>>not immediately obvious to me how his "expr_text" function (or other
>>>functions in "lazyevel") to produce a better solution.
>>>
>>>
>>>   Thanks again to David, Peter and Hadley for their replies.
>>>
>>>
>>>   Spencer Graves
>>>
>>>
>>>On 5/6/2016 5:08 PM, Hadley Wickham wrote:
 You may want to read http://rpubs.com/hadley/157957, which captures
>>>my
 latest thinking (and tooling) around this problem. Feedback is much
 appreciated.

 Hadley

 On Fri, May 6, 2016 at 2:14 PM, David Winsemius
>>> wrote:
>> On May 6, 2016, at 5:47 AM, Spencer Graves
>>> wrote:
>>
>>
>>
>> On 5/6/2016 6:46 AM, peter dalgaard wrote:
>>> On 06 May 2016, at 02:43 , David Winsemius
>>> wrote:
>>>
> On May 5, 2016, at 5:12 PM, Spencer Graves
>>> wrote:
>
> I want a function to evaluate one argument
> in the environment of a data.frame supplied
> as another argument.  "attach" works for
> this, but "with" does not.  Is there a way
> to make "with" work?  I'd rather not attach
> the data.frame.
>
>
> With the following two functions "eval.w.attach"
> works but "eval.w.with" fails:
>
>
> dat <- data.frame(a=1:2)
> eval.w.attach <- function(x, dat){
>   attach(dat)
>   X <- x
>   detach()
>   X
> }
>
> eval.w.with <- function(x, dat){
>   with(dat, x)
> }
>
> eval.w.attach(a/2, dat) # returns c(.5, 1)
 How about using eval( substitute( ...))?

 eval.w.sub <- function(expr, datt){
eval( substitute(expr), env=datt)
  }
 eval.w.sub(a/2, dat)
 #[1] 0.5 1.0


>>> Actually, I think a better overall strategy is to say that if you
>>>want to pass an expression to a function, then pass an expression
>>>object (or a call object or maybe a formula object).
>>>
>>> Once you figure out _how_ your eval.w.attach works (sort of),
>>>you'll get the creeps:
>>>
>>> Lazy evaluation causes the argument x to be evaluated after the
>>>attach(), hence the evaluation environment of an actual argument is
>>>being temporarily modified from inside a function.
>>>
>>> Apart from upsetting computer science purists, there could be
>>>hidden problems: One major issue is that  values in "dat" could be
>>>masked by values in the global environment, another issue is that an
>>>error in evaluating the expression will leave dat attached. So at a
>>>minimum, you need to recode using on.exit() magic.
>>>
>>> So my 

Re: [R] with vs. attach

2016-05-08 Thread Bert Gunter
Jeff:

That's easy to do already with substitute(), since you can pass around
an unevaluated expression (a parse tree) however you like. As I read
it, (admittedly quickly) what it's main feature is that it allows you
more control over the environment in which the expression is finally
evaluated -- as well as permitting nested expression evaluation fairly
easily.

But maybe we're saying the same thing ...  IMHO I think Hadley has
gone overboard here, worrying about rarely important issues, as you
seem to be intimating also.

Feel free to set me straight... or ignore.

Cheers,
Bert
Bert Gunter

"The trouble with having an open mind is that people keep coming along
and sticking things into it."
-- Opus (aka Berkeley Breathed in his "Bloom County" comic strip )


On Sun, May 8, 2016 at 4:02 PM, Jeff Newmiller  wrote:
> The lazyeval package addresses the problem of how to delay evaluation even 
> when the function you want to do the evaluation in is buried two or more 
> function calls below where the original call was made. If you are not 
> building nested function calls with delayed evaluation then you probably 
> don't need that package.
> --
> Sent from my phone. Please excuse my brevity.
>
> On May 8, 2016 3:30:16 PM PDT, Spencer Graves 
>  wrote:
>>Hi, Hadley et al.:
>>
>>
>>   Hadley's link requires his development version of "lazyeval",
>>which can be obtained as follows:
>>
>>
>>library(devtools)
>>install_github("hadley/lazyeval")
>>
>>
>>   Hadley's link describes real problems with elegant solutions.
>>
>>
>>   However, David's solution solved my immediate problem, and it's
>>not immediately obvious to me how his "expr_text" function (or other
>>functions in "lazyevel") to produce a better solution.
>>
>>
>>   Thanks again to David, Peter and Hadley for their replies.
>>
>>
>>   Spencer Graves
>>
>>
>>On 5/6/2016 5:08 PM, Hadley Wickham wrote:
>>> You may want to read http://rpubs.com/hadley/157957, which captures
>>my
>>> latest thinking (and tooling) around this problem. Feedback is much
>>> appreciated.
>>>
>>> Hadley
>>>
>>> On Fri, May 6, 2016 at 2:14 PM, David Winsemius
>> wrote:
> On May 6, 2016, at 5:47 AM, Spencer Graves
>> wrote:
>
>
>
> On 5/6/2016 6:46 AM, peter dalgaard wrote:
>> On 06 May 2016, at 02:43 , David Winsemius
>> wrote:
>>
 On May 5, 2016, at 5:12 PM, Spencer Graves
>> wrote:

 I want a function to evaluate one argument
 in the environment of a data.frame supplied
 as another argument.  "attach" works for
 this, but "with" does not.  Is there a way
 to make "with" work?  I'd rather not attach
 the data.frame.


 With the following two functions "eval.w.attach"
 works but "eval.w.with" fails:


 dat <- data.frame(a=1:2)
 eval.w.attach <- function(x, dat){
   attach(dat)
   X <- x
   detach()
   X
 }

 eval.w.with <- function(x, dat){
   with(dat, x)
 }

 eval.w.attach(a/2, dat) # returns c(.5, 1)
>>> How about using eval( substitute( ...))?
>>>
>>> eval.w.sub <- function(expr, datt){
>>>eval( substitute(expr), env=datt)
>>>  }
>>> eval.w.sub(a/2, dat)
>>> #[1] 0.5 1.0
>>>
>>>
>> Actually, I think a better overall strategy is to say that if you
>>want to pass an expression to a function, then pass an expression
>>object (or a call object or maybe a formula object).
>>
>> Once you figure out _how_ your eval.w.attach works (sort of),
>>you'll get the creeps:
>>
>> Lazy evaluation causes the argument x to be evaluated after the
>>attach(), hence the evaluation environment of an actual argument is
>>being temporarily modified from inside a function.
>>
>> Apart from upsetting computer science purists, there could be
>>hidden problems: One major issue is that  values in "dat" could be
>>masked by values in the global environment, another issue is that an
>>error in evaluating the expression will leave dat attached. So at a
>>minimum, you need to recode using on.exit() magic.
>>
>> So my preferences go along these lines:
>>
>>> dat <- data.frame(a=1:2)
>>> eval.expression <- function(e, dat) eval(e, dat)
>>> eval.expression(quote(a/2), dat)
>> [1] 0.5 1.0
>>> eval.expression(expression(a/2), dat)
>> [1] 0.5 1.0
>>
>>> eval.formula <- function(f, dat) eval(f[[2]], dat)
>>> eval.formula(~a/2, dat)
>> [1] 0.5 1.0
> Hi, Peter:
>
>
>   I don't like eval.expression or eval.formula, because they
>>don't automatically accept what I naively thought should work and
>>require more knowledge 

Re: [R] with vs. attach

2016-05-08 Thread Jeff Newmiller
The lazyeval package addresses the problem of how to delay evaluation even when 
the function you want to do the evaluation in is buried two or more function 
calls below where the original call was made. If you are not building nested 
function calls with delayed evaluation then you probably don't need that 
package. 
-- 
Sent from my phone. Please excuse my brevity.

On May 8, 2016 3:30:16 PM PDT, Spencer Graves 
 wrote:
>Hi, Hadley et al.:
>
>
>   Hadley's link requires his development version of "lazyeval", 
>which can be obtained as follows:
>
>
>library(devtools)
>install_github("hadley/lazyeval")
>
>
>   Hadley's link describes real problems with elegant solutions.
>
>
>   However, David's solution solved my immediate problem, and it's 
>not immediately obvious to me how his "expr_text" function (or other 
>functions in "lazyevel") to produce a better solution.
>
>
>   Thanks again to David, Peter and Hadley for their replies.
>
>
>   Spencer Graves
>
>
>On 5/6/2016 5:08 PM, Hadley Wickham wrote:
>> You may want to read http://rpubs.com/hadley/157957, which captures
>my
>> latest thinking (and tooling) around this problem. Feedback is much
>> appreciated.
>>
>> Hadley
>>
>> On Fri, May 6, 2016 at 2:14 PM, David Winsemius
> wrote:
 On May 6, 2016, at 5:47 AM, Spencer Graves
> wrote:



 On 5/6/2016 6:46 AM, peter dalgaard wrote:
> On 06 May 2016, at 02:43 , David Winsemius
> wrote:
>
>>> On May 5, 2016, at 5:12 PM, Spencer Graves
> wrote:
>>>
>>> I want a function to evaluate one argument
>>> in the environment of a data.frame supplied
>>> as another argument.  "attach" works for
>>> this, but "with" does not.  Is there a way
>>> to make "with" work?  I'd rather not attach
>>> the data.frame.
>>>
>>>
>>> With the following two functions "eval.w.attach"
>>> works but "eval.w.with" fails:
>>>
>>>
>>> dat <- data.frame(a=1:2)
>>> eval.w.attach <- function(x, dat){
>>>   attach(dat)
>>>   X <- x
>>>   detach()
>>>   X
>>> }
>>>
>>> eval.w.with <- function(x, dat){
>>>   with(dat, x)
>>> }
>>>
>>> eval.w.attach(a/2, dat) # returns c(.5, 1)
>> How about using eval( substitute( ...))?
>>
>> eval.w.sub <- function(expr, datt){
>>eval( substitute(expr), env=datt)
>>  }
>> eval.w.sub(a/2, dat)
>> #[1] 0.5 1.0
>>
>>
> Actually, I think a better overall strategy is to say that if you
>want to pass an expression to a function, then pass an expression
>object (or a call object or maybe a formula object).
>
> Once you figure out _how_ your eval.w.attach works (sort of),
>you'll get the creeps:
>
> Lazy evaluation causes the argument x to be evaluated after the
>attach(), hence the evaluation environment of an actual argument is
>being temporarily modified from inside a function.
>
> Apart from upsetting computer science purists, there could be
>hidden problems: One major issue is that  values in "dat" could be
>masked by values in the global environment, another issue is that an
>error in evaluating the expression will leave dat attached. So at a
>minimum, you need to recode using on.exit() magic.
>
> So my preferences go along these lines:
>
>> dat <- data.frame(a=1:2)
>> eval.expression <- function(e, dat) eval(e, dat)
>> eval.expression(quote(a/2), dat)
> [1] 0.5 1.0
>> eval.expression(expression(a/2), dat)
> [1] 0.5 1.0
>
>> eval.formula <- function(f, dat) eval(f[[2]], dat)
>> eval.formula(~a/2, dat)
> [1] 0.5 1.0
 Hi, Peter:


   I don't like eval.expression or eval.formula, because they
>don't automatically accept what I naively thought should work and
>require more knowledge of the user.  What about David's eval.w.sub:


 a <- pi
 dat <- data.frame(a=1:2)
 eval.w.sub <- function(a, Dat){
   eval( substitute(a), env=Dat)
 }
> eval.w.sub(a/2, dat)
 [1] 0.5 1.0
>>> I liked eval.expression and tested it with a bquote(...) argument to
>see if that would succeed. It did, but it didn't return what you wanted
>for `a/2`, so I tried seeing if a "double eval wuold deliver both yours
>and my desired results:
>>>
>>>   eval.w.sub <- function(a, Dat){
>>>eval( eval(substitute(a),Dat), env=Dat)
>>>   }
>>> x=2
>>>   eval.w.sub( a/2, dat)
>>> [1] 0.5 1.0
>>>   eval.w.sub( bquote(2*a*.(x) ), dat)
>>> [1] 4 8
>>>
>>> We are here retracing the path the Hadley took in some of his
>ggplot2 design decsions. Unfortunately for me those NSE rules often
>left me confused about what should and shouldn't be 'quoted' in the
>as-character sense and what should be quote()-ed or "unquoted" in the
>bquote() sense.
>>> --
>>>

Re: [R] with vs. attach

2016-05-08 Thread Spencer Graves

Hi, Hadley et al.:


  Hadley's link requires his development version of "lazyeval", 
which can be obtained as follows:



library(devtools)
install_github("hadley/lazyeval")


  Hadley's link describes real problems with elegant solutions.


  However, David's solution solved my immediate problem, and it's 
not immediately obvious to me how his "expr_text" function (or other 
functions in "lazyevel") to produce a better solution.



  Thanks again to David, Peter and Hadley for their replies.


  Spencer Graves


On 5/6/2016 5:08 PM, Hadley Wickham wrote:

You may want to read http://rpubs.com/hadley/157957, which captures my
latest thinking (and tooling) around this problem. Feedback is much
appreciated.

Hadley

On Fri, May 6, 2016 at 2:14 PM, David Winsemius  wrote:

On May 6, 2016, at 5:47 AM, Spencer Graves 
 wrote:



On 5/6/2016 6:46 AM, peter dalgaard wrote:

On 06 May 2016, at 02:43 , David Winsemius  wrote:


On May 5, 2016, at 5:12 PM, Spencer Graves 
 wrote:

I want a function to evaluate one argument
in the environment of a data.frame supplied
as another argument.  "attach" works for
this, but "with" does not.  Is there a way
to make "with" work?  I'd rather not attach
the data.frame.


With the following two functions "eval.w.attach"
works but "eval.w.with" fails:


dat <- data.frame(a=1:2)
eval.w.attach <- function(x, dat){
  attach(dat)
  X <- x
  detach()
  X
}

eval.w.with <- function(x, dat){
  with(dat, x)
}

eval.w.attach(a/2, dat) # returns c(.5, 1)

How about using eval( substitute( ...))?

eval.w.sub <- function(expr, datt){
   eval( substitute(expr), env=datt)
 }
eval.w.sub(a/2, dat)
#[1] 0.5 1.0



Actually, I think a better overall strategy is to say that if you want to pass 
an expression to a function, then pass an expression object (or a call object 
or maybe a formula object).

Once you figure out _how_ your eval.w.attach works (sort of), you'll get the 
creeps:

Lazy evaluation causes the argument x to be evaluated after the attach(), hence 
the evaluation environment of an actual argument is being temporarily modified 
from inside a function.

Apart from upsetting computer science purists, there could be hidden problems: One major 
issue is that  values in "dat" could be masked by values in the global 
environment, another issue is that an error in evaluating the expression will leave dat 
attached. So at a minimum, you need to recode using on.exit() magic.

So my preferences go along these lines:


dat <- data.frame(a=1:2)
eval.expression <- function(e, dat) eval(e, dat)
eval.expression(quote(a/2), dat)

[1] 0.5 1.0

eval.expression(expression(a/2), dat)

[1] 0.5 1.0


eval.formula <- function(f, dat) eval(f[[2]], dat)
eval.formula(~a/2, dat)

[1] 0.5 1.0

Hi, Peter:


  I don't like eval.expression or eval.formula, because they don't 
automatically accept what I naively thought should work and require more 
knowledge of the user.  What about David's eval.w.sub:


a <- pi
dat <- data.frame(a=1:2)
eval.w.sub <- function(a, Dat){
  eval( substitute(a), env=Dat)
}

eval.w.sub(a/2, dat)

[1] 0.5 1.0

I liked eval.expression and tested it with a bquote(...) argument to see if that 
would succeed. It did, but it didn't return what you wanted for `a/2`, so I tried 
seeing if a "double eval wuold deliver both yours and my desired results:

  eval.w.sub <- function(a, Dat){
   eval( eval(substitute(a),Dat), env=Dat)
  }
x=2
  eval.w.sub( a/2, dat)
[1] 0.5 1.0
  eval.w.sub( bquote(2*a*.(x) ), dat)
[1] 4 8

We are here retracing the path the Hadley took in some of his ggplot2 design decsions. 
Unfortunately for me those NSE rules often left me confused about what should and 
shouldn't be 'quoted' in the as-character sense and what should be quote()-ed or 
"unquoted" in the bquote() sense.
--




  This produces what's desired in a way that seems simpler to me.


  By the way, I really appreciate Peter's insightful comments:


eval.w.attachOops <- function(x, Dat){
  attach(Dat)
  X <- x
  detach()
  X
}

eval.w.attachOops(a/2, dat)

The following object is masked _by_ .GlobalEnv:

a

[1] 1.570796

eval.w.attachOops(b/2, dat)

The following object is masked _by_ .GlobalEnv:

a

Error in eval.w.attachOops(b/2, dat) : object 'b' not found

search()

[1] ".GlobalEnv""Dat"   "package:graphics"
[4] "package:grDevices" "package:utils" "package:datasets"
[7] "package:methods"   "Autoloads" "package:base"

objects(2)

[1] "a"

*** NOTES:


  1.  This gives a likely wrong answer with a warning if "a" exists in .GlobalEnv, and leaves 
"Dat" (NOT "dat") attached upon exit.



  2.  A stray "detach()" [not shown here] detached "package:stats".  oops.


*** Using "on.exit" fixes the problem with failure to detach but not the likely 
wrong answer:


detach()
search()

Re: [R] with vs. attach

2016-05-06 Thread Hadley Wickham
You may want to read http://rpubs.com/hadley/157957, which captures my
latest thinking (and tooling) around this problem. Feedback is much
appreciated.

Hadley

On Fri, May 6, 2016 at 2:14 PM, David Winsemius  wrote:
>
>> On May 6, 2016, at 5:47 AM, Spencer Graves 
>>  wrote:
>>
>>
>>
>> On 5/6/2016 6:46 AM, peter dalgaard wrote:
>>> On 06 May 2016, at 02:43 , David Winsemius  wrote:
>>>
> On May 5, 2016, at 5:12 PM, Spencer Graves 
>  wrote:
>
> I want a function to evaluate one argument
> in the environment of a data.frame supplied
> as another argument.  "attach" works for
> this, but "with" does not.  Is there a way
> to make "with" work?  I'd rather not attach
> the data.frame.
>
>
> With the following two functions "eval.w.attach"
> works but "eval.w.with" fails:
>
>
> dat <- data.frame(a=1:2)
> eval.w.attach <- function(x, dat){
>  attach(dat)
>  X <- x
>  detach()
>  X
> }
>
> eval.w.with <- function(x, dat){
>  with(dat, x)
> }
>
> eval.w.attach(a/2, dat) # returns c(.5, 1)
 How about using eval( substitute( ...))?

 eval.w.sub <- function(expr, datt){
   eval( substitute(expr), env=datt)
 }
 eval.w.sub(a/2, dat)
 #[1] 0.5 1.0


>>> Actually, I think a better overall strategy is to say that if you want to 
>>> pass an expression to a function, then pass an expression object (or a call 
>>> object or maybe a formula object).
>>>
>>> Once you figure out _how_ your eval.w.attach works (sort of), you'll get 
>>> the creeps:
>>>
>>> Lazy evaluation causes the argument x to be evaluated after the attach(), 
>>> hence the evaluation environment of an actual argument is being temporarily 
>>> modified from inside a function.
>>>
>>> Apart from upsetting computer science purists, there could be hidden 
>>> problems: One major issue is that  values in "dat" could be masked by 
>>> values in the global environment, another issue is that an error in 
>>> evaluating the expression will leave dat attached. So at a minimum, you 
>>> need to recode using on.exit() magic.
>>>
>>> So my preferences go along these lines:
>>>
 dat <- data.frame(a=1:2)
 eval.expression <- function(e, dat) eval(e, dat)
 eval.expression(quote(a/2), dat)
>>> [1] 0.5 1.0
 eval.expression(expression(a/2), dat)
>>> [1] 0.5 1.0
>>>
 eval.formula <- function(f, dat) eval(f[[2]], dat)
 eval.formula(~a/2, dat)
>>> [1] 0.5 1.0
>>
>> Hi, Peter:
>>
>>
>>  I don't like eval.expression or eval.formula, because they don't 
>> automatically accept what I naively thought should work and require more 
>> knowledge of the user.  What about David's eval.w.sub:
>>
>>
>> a <- pi
>> dat <- data.frame(a=1:2)
>> eval.w.sub <- function(a, Dat){
>>  eval( substitute(a), env=Dat)
>> }
>> > eval.w.sub(a/2, dat)
>> [1] 0.5 1.0
>
> I liked eval.expression and tested it with a bquote(...) argument to see if 
> that would succeed. It did, but it didn't return what you wanted for `a/2`, 
> so I tried seeing if a "double eval wuold deliver both yours and my desired 
> results:
>
>  eval.w.sub <- function(a, Dat){
>   eval( eval(substitute(a),Dat), env=Dat)
>  }
> x=2
>  eval.w.sub( a/2, dat)
> [1] 0.5 1.0
>  eval.w.sub( bquote(2*a*.(x) ), dat)
> [1] 4 8
>
> We are here retracing the path the Hadley took in some of his ggplot2 design 
> decsions. Unfortunately for me those NSE rules often left me confused about 
> what should and shouldn't be 'quoted' in the as-character sense and what 
> should be quote()-ed or "unquoted" in the bquote() sense.
> --
>
>>
>>
>>
>>  This produces what's desired in a way that seems simpler to me.
>>
>>
>>  By the way, I really appreciate Peter's insightful comments:
>>
>>
>> eval.w.attachOops <- function(x, Dat){
>>  attach(Dat)
>>  X <- x
>>  detach()
>>  X
>> }
>> > eval.w.attachOops(a/2, dat)
>> The following object is masked _by_ .GlobalEnv:
>>
>>a
>>
>> [1] 1.570796
>> > eval.w.attachOops(b/2, dat)
>> The following object is masked _by_ .GlobalEnv:
>>
>>a
>>
>> Error in eval.w.attachOops(b/2, dat) : object 'b' not found
>> > search()
>> [1] ".GlobalEnv""Dat"   "package:graphics"
>> [4] "package:grDevices" "package:utils" "package:datasets"
>> [7] "package:methods"   "Autoloads" "package:base"
>> > objects(2)
>> [1] "a"
>>
>> *** NOTES:
>>
>>
>>  1.  This gives a likely wrong answer with a warning if "a" exists in 
>> .GlobalEnv, and leaves "Dat" (NOT "dat") attached upon exit.
>>
>>
>>
>>  2.  A stray "detach()" [not shown here] detached "package:stats".  oops.
>>
>>
>> *** Using "on.exit" fixes the problem with failure to detach but not the 
>> likely wrong answer:
>>
>>
>> detach()
>> search()
>> eval.w.attachStillWrong <- function(x, dat){
>>  attach(dat)
>>  

Re: [R] with vs. attach

2016-05-06 Thread David Winsemius

> On May 6, 2016, at 5:47 AM, Spencer Graves 
>  wrote:
> 
> 
> 
> On 5/6/2016 6:46 AM, peter dalgaard wrote:
>> On 06 May 2016, at 02:43 , David Winsemius  wrote:
>> 
 On May 5, 2016, at 5:12 PM, Spencer Graves 
  wrote:
 
 I want a function to evaluate one argument
 in the environment of a data.frame supplied
 as another argument.  "attach" works for
 this, but "with" does not.  Is there a way
 to make "with" work?  I'd rather not attach
 the data.frame.
 
 
 With the following two functions "eval.w.attach"
 works but "eval.w.with" fails:
 
 
 dat <- data.frame(a=1:2)
 eval.w.attach <- function(x, dat){
  attach(dat)
  X <- x
  detach()
  X
 }
 
 eval.w.with <- function(x, dat){
  with(dat, x)
 }
 
 eval.w.attach(a/2, dat) # returns c(.5, 1)
>>> How about using eval( substitute( ...))?
>>> 
>>> eval.w.sub <- function(expr, datt){
>>>   eval( substitute(expr), env=datt)
>>> }
>>> eval.w.sub(a/2, dat)
>>> #[1] 0.5 1.0
>>> 
>>> 
>> Actually, I think a better overall strategy is to say that if you want to 
>> pass an expression to a function, then pass an expression object (or a call 
>> object or maybe a formula object).
>> 
>> Once you figure out _how_ your eval.w.attach works (sort of), you'll get the 
>> creeps:
>> 
>> Lazy evaluation causes the argument x to be evaluated after the attach(), 
>> hence the evaluation environment of an actual argument is being temporarily 
>> modified from inside a function.
>> 
>> Apart from upsetting computer science purists, there could be hidden 
>> problems: One major issue is that  values in "dat" could be masked by values 
>> in the global environment, another issue is that an error in evaluating the 
>> expression will leave dat attached. So at a minimum, you need to recode 
>> using on.exit() magic.
>> 
>> So my preferences go along these lines:
>> 
>>> dat <- data.frame(a=1:2)
>>> eval.expression <- function(e, dat) eval(e, dat)
>>> eval.expression(quote(a/2), dat)
>> [1] 0.5 1.0
>>> eval.expression(expression(a/2), dat)
>> [1] 0.5 1.0
>> 
>>> eval.formula <- function(f, dat) eval(f[[2]], dat)
>>> eval.formula(~a/2, dat)
>> [1] 0.5 1.0
> 
> Hi, Peter:
> 
> 
>  I don't like eval.expression or eval.formula, because they don't 
> automatically accept what I naively thought should work and require more 
> knowledge of the user.  What about David's eval.w.sub:
> 
> 
> a <- pi
> dat <- data.frame(a=1:2)
> eval.w.sub <- function(a, Dat){
>  eval( substitute(a), env=Dat)
> }
> > eval.w.sub(a/2, dat)
> [1] 0.5 1.0

I liked eval.expression and tested it with a bquote(...) argument to see if 
that would succeed. It did, but it didn't return what you wanted for `a/2`, so 
I tried seeing if a "double eval wuold deliver both yours and my desired 
results:

 eval.w.sub <- function(a, Dat){
  eval( eval(substitute(a),Dat), env=Dat)
 }
x=2
 eval.w.sub( a/2, dat)
[1] 0.5 1.0
 eval.w.sub( bquote(2*a*.(x) ), dat)
[1] 4 8

We are here retracing the path the Hadley took in some of his ggplot2 design 
decsions. Unfortunately for me those NSE rules often left me confused about 
what should and shouldn't be 'quoted' in the as-character sense and what should 
be quote()-ed or "unquoted" in the bquote() sense.
-- 

> 
> 
> 
>  This produces what's desired in a way that seems simpler to me.
> 
> 
>  By the way, I really appreciate Peter's insightful comments:
> 
> 
> eval.w.attachOops <- function(x, Dat){
>  attach(Dat)
>  X <- x
>  detach()
>  X
> }
> > eval.w.attachOops(a/2, dat)
> The following object is masked _by_ .GlobalEnv:
> 
>a
> 
> [1] 1.570796
> > eval.w.attachOops(b/2, dat)
> The following object is masked _by_ .GlobalEnv:
> 
>a
> 
> Error in eval.w.attachOops(b/2, dat) : object 'b' not found
> > search()
> [1] ".GlobalEnv""Dat"   "package:graphics"
> [4] "package:grDevices" "package:utils" "package:datasets"
> [7] "package:methods"   "Autoloads" "package:base"
> > objects(2)
> [1] "a"
> 
> *** NOTES:
> 
> 
>  1.  This gives a likely wrong answer with a warning if "a" exists in 
> .GlobalEnv, and leaves "Dat" (NOT "dat") attached upon exit.
> 
> 
> 
>  2.  A stray "detach()" [not shown here] detached "package:stats".  oops.
> 
> 
> *** Using "on.exit" fixes the problem with failure to detach but not the 
> likely wrong answer:
> 
> 
> detach()
> search()
> eval.w.attachStillWrong <- function(x, dat){
>  attach(dat)
>  on.exit(detach(dat))
>  X <- x
>  X
> }
> The following object is masked _by_ .GlobalEnv:
> 
>a
> 
> [1] 1.570796
> > eval.w.attachStillWrong(b/2, dat)
> The following object is masked _by_ .GlobalEnv:
> 
>a
> 
> Error in eval.w.attachStillWrong(b/2, dat) : object 'b' not found
> > search()
> [1] ".GlobalEnv""package:grDevices" "package:utils"
> [4] 

Re: [R] with vs. attach

2016-05-06 Thread Spencer Graves



On 5/6/2016 6:46 AM, peter dalgaard wrote:

On 06 May 2016, at 02:43 , David Winsemius  wrote:


On May 5, 2016, at 5:12 PM, Spencer Graves 
 wrote:

I want a function to evaluate one argument
in the environment of a data.frame supplied
as another argument.  "attach" works for
this, but "with" does not.  Is there a way
to make "with" work?  I'd rather not attach
the data.frame.


With the following two functions "eval.w.attach"
works but "eval.w.with" fails:


dat <- data.frame(a=1:2)
eval.w.attach <- function(x, dat){
  attach(dat)
  X <- x
  detach()
  X
}

eval.w.with <- function(x, dat){
  with(dat, x)
}

eval.w.attach(a/2, dat) # returns c(.5, 1)

How about using eval( substitute( ...))?

eval.w.sub <- function(expr, datt){
   eval( substitute(expr), env=datt)
 }
eval.w.sub(a/2, dat)
#[1] 0.5 1.0



Actually, I think a better overall strategy is to say that if you want to pass 
an expression to a function, then pass an expression object (or a call object 
or maybe a formula object).

Once you figure out _how_ your eval.w.attach works (sort of), you'll get the 
creeps:

Lazy evaluation causes the argument x to be evaluated after the attach(), hence 
the evaluation environment of an actual argument is being temporarily modified 
from inside a function.

Apart from upsetting computer science purists, there could be hidden problems: One major 
issue is that  values in "dat" could be masked by values in the global 
environment, another issue is that an error in evaluating the expression will leave dat 
attached. So at a minimum, you need to recode using on.exit() magic.

So my preferences go along these lines:


dat <- data.frame(a=1:2)
eval.expression <- function(e, dat) eval(e, dat)
eval.expression(quote(a/2), dat)

[1] 0.5 1.0

eval.expression(expression(a/2), dat)

[1] 0.5 1.0


eval.formula <- function(f, dat) eval(f[[2]], dat)
eval.formula(~a/2, dat)

[1] 0.5 1.0


Hi, Peter:


  I don't like eval.expression or eval.formula, because they don't 
automatically accept what I naively thought should work and require more 
knowledge of the user.  What about David's eval.w.sub:



a <- pi
dat <- data.frame(a=1:2)
eval.w.sub <- function(a, Dat){
  eval( substitute(a), env=Dat)
}
> eval.w.sub(a/2, dat)
[1] 0.5 1.0


  This produces what's desired in a way that seems simpler to me.


  By the way, I really appreciate Peter's insightful comments:


eval.w.attachOops <- function(x, Dat){
  attach(Dat)
  X <- x
  detach()
  X
}
> eval.w.attachOops(a/2, dat)
The following object is masked _by_ .GlobalEnv:

a

[1] 1.570796
> eval.w.attachOops(b/2, dat)
The following object is masked _by_ .GlobalEnv:

a

Error in eval.w.attachOops(b/2, dat) : object 'b' not found
> search()
[1] ".GlobalEnv""Dat"   "package:graphics"
[4] "package:grDevices" "package:utils" "package:datasets"
[7] "package:methods"   "Autoloads" "package:base"
> objects(2)
[1] "a"

*** NOTES:


  1.  This gives a likely wrong answer with a warning if "a" exists 
in .GlobalEnv, and leaves "Dat" (NOT "dat") attached upon exit.




  2.  A stray "detach()" [not shown here] detached 
"package:stats".  oops.



*** Using "on.exit" fixes the problem with failure to detach but not the 
likely wrong answer:



detach()
search()
eval.w.attachStillWrong <- function(x, dat){
  attach(dat)
  on.exit(detach(dat))
  X <- x
  X
}
The following object is masked _by_ .GlobalEnv:

a

[1] 1.570796
> eval.w.attachStillWrong(b/2, dat)
The following object is masked _by_ .GlobalEnv:

a

Error in eval.w.attachStillWrong(b/2, dat) : object 'b' not found
> search()
[1] ".GlobalEnv""package:grDevices" "package:utils"
[4] "package:datasets"  "package:methods"   "Autoloads"
[7] "package:base"


  Thanks again to Peter and David.  Spencer


Peter D.




--
David.



eval.w.with(a/2, dat) # Error ... 'a' not found


Thanks, Spencer Graves

[[alternative HTML version deleted]]

__
R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see
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.

David Winsemius
Alameda, CA, USA

__
R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see
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.


__
R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see
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.


Re: [R] with vs. attach

2016-05-06 Thread peter dalgaard

On 06 May 2016, at 02:43 , David Winsemius  wrote:

> 
>> On May 5, 2016, at 5:12 PM, Spencer Graves 
>>  wrote:
>> 
>> I want a function to evaluate one argument
>> in the environment of a data.frame supplied
>> as another argument.  "attach" works for
>> this, but "with" does not.  Is there a way
>> to make "with" work?  I'd rather not attach
>> the data.frame.
>> 
>> 
>> With the following two functions "eval.w.attach"
>> works but "eval.w.with" fails:
>> 
>> 
>> dat <- data.frame(a=1:2)
>> eval.w.attach <- function(x, dat){
>>  attach(dat)
>>  X <- x
>>  detach()
>>  X
>> }
>> 
>> eval.w.with <- function(x, dat){
>>  with(dat, x)
>> }
>> 
>> eval.w.attach(a/2, dat) # returns c(.5, 1)
> 
> How about using eval( substitute( ...))?
> 
> eval.w.sub <- function(expr, datt){
>   eval( substitute(expr), env=datt)
> }
> eval.w.sub(a/2, dat)
> #[1] 0.5 1.0
> 
> 

Actually, I think a better overall strategy is to say that if you want to pass 
an expression to a function, then pass an expression object (or a call object 
or maybe a formula object). 

Once you figure out _how_ your eval.w.attach works (sort of), you'll get the 
creeps: 

Lazy evaluation causes the argument x to be evaluated after the attach(), hence 
the evaluation environment of an actual argument is being temporarily modified 
from inside a function. 

Apart from upsetting computer science purists, there could be hidden problems: 
One major issue is that  values in "dat" could be masked by values in the 
global environment, another issue is that an error in evaluating the expression 
will leave dat attached. So at a minimum, you need to recode using on.exit() 
magic.

So my preferences go along these lines:

> dat <- data.frame(a=1:2)
> eval.expression <- function(e, dat) eval(e, dat)
> eval.expression(quote(a/2), dat)
[1] 0.5 1.0
> eval.expression(expression(a/2), dat)
[1] 0.5 1.0

> eval.formula <- function(f, dat) eval(f[[2]], dat)
> eval.formula(~a/2, dat)
[1] 0.5 1.0

Peter D.



> -- 
> David.
> 
> 
>> 
>> eval.w.with(a/2, dat) # Error ... 'a' not found
>> 
>> 
>> Thanks, Spencer Graves
>> 
>>  [[alternative HTML version deleted]]
>> 
>> __
>> R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see
>> 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.
> 
> David Winsemius
> Alameda, CA, USA
> 
> __
> R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see
> 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.

-- 
Peter Dalgaard, Professor,
Center for Statistics, Copenhagen Business School
Solbjerg Plads 3, 2000 Frederiksberg, Denmark
Phone: (+45)38153501
Office: A 4.23
Email: pd@cbs.dk  Priv: pda...@gmail.com

__
R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see
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.


Re: [R] with vs. attach

2016-05-06 Thread Spencer Graves



On 5/5/2016 11:17 PM, Bert Gunter wrote:

... and it's exactly with.default's code !



Thanks for pointing that out.  Unfortunately, it didn't work inside 
another function.  However, if I had looked at it, I might have been 
able to thought to try it.  Spencer


Cheers,
Bert


Bert Gunter

"The trouble with having an open mind is that people keep coming along
and sticking things into it."
-- Opus (aka Berkeley Breathed in his "Bloom County" comic strip )


On Thu, May 5, 2016 at 7:38 PM, Spencer Graves
 wrote:

Hi, David:  That works.  Thanks very much.  Spencer Graves



On 5/5/2016 7:43 PM, David Winsemius wrote:

On May 5, 2016, at 5:12 PM, Spencer Graves
 wrote:

I want a function to evaluate one argument
in the environment of a data.frame supplied
as another argument.  "attach" works for
this, but "with" does not.  Is there a way
to make "with" work?  I'd rather not attach
the data.frame.


With the following two functions "eval.w.attach"
works but "eval.w.with" fails:


dat <- data.frame(a=1:2)
eval.w.attach <- function(x, dat){
attach(dat)
X <- x
detach()
X
}

eval.w.with <- function(x, dat){
with(dat, x)
}

eval.w.attach(a/2, dat) # returns c(.5, 1)

How about using eval( substitute( ...))?

   eval.w.sub <- function(expr, datt){
 eval( substitute(expr), env=datt)
   }
   eval.w.sub(a/2, dat)
#[1] 0.5 1.0



__
R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see
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.


__
R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see
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.


Re: [R] with vs. attach

2016-05-05 Thread Bert Gunter
... and it's exactly with.default's code !

Cheers,
Bert


Bert Gunter

"The trouble with having an open mind is that people keep coming along
and sticking things into it."
-- Opus (aka Berkeley Breathed in his "Bloom County" comic strip )


On Thu, May 5, 2016 at 7:38 PM, Spencer Graves
 wrote:
> Hi, David:  That works.  Thanks very much.  Spencer Graves
>
>
>
> On 5/5/2016 7:43 PM, David Winsemius wrote:
>>>
>>> On May 5, 2016, at 5:12 PM, Spencer Graves
>>>  wrote:
>>>
>>> I want a function to evaluate one argument
>>> in the environment of a data.frame supplied
>>> as another argument.  "attach" works for
>>> this, but "with" does not.  Is there a way
>>> to make "with" work?  I'd rather not attach
>>> the data.frame.
>>>
>>>
>>> With the following two functions "eval.w.attach"
>>> works but "eval.w.with" fails:
>>>
>>>
>>> dat <- data.frame(a=1:2)
>>> eval.w.attach <- function(x, dat){
>>>attach(dat)
>>>X <- x
>>>detach()
>>>X
>>> }
>>>
>>> eval.w.with <- function(x, dat){
>>>with(dat, x)
>>> }
>>>
>>> eval.w.attach(a/2, dat) # returns c(.5, 1)
>>
>> How about using eval( substitute( ...))?
>>
>>   eval.w.sub <- function(expr, datt){
>> eval( substitute(expr), env=datt)
>>   }
>>   eval.w.sub(a/2, dat)
>> #[1] 0.5 1.0
>>
>>
>
> __
> R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see
> 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.

__
R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see
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.


Re: [R] with vs. attach

2016-05-05 Thread Spencer Graves

Hi, David:  That works.  Thanks very much.  Spencer Graves



On 5/5/2016 7:43 PM, David Winsemius wrote:

On May 5, 2016, at 5:12 PM, Spencer Graves 
 wrote:

I want a function to evaluate one argument
in the environment of a data.frame supplied
as another argument.  "attach" works for
this, but "with" does not.  Is there a way
to make "with" work?  I'd rather not attach
the data.frame.


With the following two functions "eval.w.attach"
works but "eval.w.with" fails:


dat <- data.frame(a=1:2)
eval.w.attach <- function(x, dat){
   attach(dat)
   X <- x
   detach()
   X
}

eval.w.with <- function(x, dat){
   with(dat, x)
}

eval.w.attach(a/2, dat) # returns c(.5, 1)

How about using eval( substitute( ...))?

  eval.w.sub <- function(expr, datt){
eval( substitute(expr), env=datt)
  }
  eval.w.sub(a/2, dat)
#[1] 0.5 1.0




__
R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see
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.


Re: [R] with vs. attach

2016-05-05 Thread David Winsemius

> On May 5, 2016, at 5:12 PM, Spencer Graves 
>  wrote:
> 
> I want a function to evaluate one argument
> in the environment of a data.frame supplied
> as another argument.  "attach" works for
> this, but "with" does not.  Is there a way
> to make "with" work?  I'd rather not attach
> the data.frame.
> 
> 
> With the following two functions "eval.w.attach"
> works but "eval.w.with" fails:
> 
> 
> dat <- data.frame(a=1:2)
> eval.w.attach <- function(x, dat){
>   attach(dat)
>   X <- x
>   detach()
>   X
> }
> 
> eval.w.with <- function(x, dat){
>   with(dat, x)
> }
> 
> eval.w.attach(a/2, dat) # returns c(.5, 1)

How about using eval( substitute( ...))?

 eval.w.sub <- function(expr, datt){
   eval( substitute(expr), env=datt)
 }
 eval.w.sub(a/2, dat)
#[1] 0.5 1.0


-- 
David.


> 
> eval.w.with(a/2, dat) # Error ... 'a' not found
> 
> 
> Thanks, Spencer Graves
> 
>   [[alternative HTML version deleted]]
> 
> __
> R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see
> 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.

David Winsemius
Alameda, CA, USA

__
R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see
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.


Re: [R] source() vs attach()0

2009-11-11 Thread Stefan Zeugner


Duncan Murdoch wrote:

Just declaring it there is the only reasonable way, i.e.

test-function(foo) {
  subtest - function() {
 foo - foo+1
  }
  subtest()
  return(foo)
}

The reason you can't somehow assign it within an existing test is that 
subtest is a different closure every time.  Its environment will be 
the local frame of the call to test, so the foo on the right hand 
side of the assignment will be the value that was passed to test.


An unreasonable way to get what you want is to mess with the 
environment, e.g.


subtest - function() {
   foo - foo+1
}

test - function(foo) {
   mysubtest - subtest  # make a local copy
   environment(mysubtest) - environment()  # attach the local frame

   mysubtest()
   return(foo)
}

This is ugly programming, likely to bite you at some future date.

Duncan Murdoch



Duncan,
Thank you a lot for this clarification.
Unfortunately, I have to get through this at the moment: I have 
subfunctions that are to be used by in the environments of several 
'main' functions: and I prefer not to declare them separately each time.

Therefore I will have to mess with the environment (for now) :-(

In this case, would it be wiser to shift the 'environment messing' to 
the subfunction?
I.e. tell it to manipulate its respective parent environment, as in the 
example below?


subtest - function() {
eval(expression(foo - foo+1),parent.frame())
}

test - function(foo) {
  subtest()
  return(foo)
}


Stefan

__
R-help@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.