[R] with vs. attach

Hadley Wickham h.wickham at gmail.com
Mon May 9 14:31:39 CEST 2016


On Mon, May 9, 2016 at 7:12 AM, peter dalgaard <pdalgd at gmail.com> wrote:
>
> On 09 May 2016, at 02:46 , Bert Gunter <bgunter.4567 at gmail.com> 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



More information about the R-help mailing list