[Rd] Puzzled by eval

Duncan Murdoch murdoch.duncan at gmail.com
Fri Nov 6 15:47:33 CET 2015

On 06/11/2015 8:20 AM, Therneau, Terry M., Ph.D. wrote:
> Duncan,
>     That's helpful.  Two follow-up questions:
> 1. Where would I have found this information?  I had looked at eval and model.frame.

I think the best description is Luke's article on namespaces, "Name 
space management for R". Luke Tierney, R News, 3(1):2-6, June 2003. 
There's a link to it from the "Technical papers" section of the HTML 
help index.  There's also a short description of this in the R Language 
Definition manual in the "Search path" section 3.5.4.

> 2. What stops the following code from falling down the same rabbit hole?  Shouldn't it
> find base::cos first?
>      library(survival)
>      cos <- lung
>      coxph(Surv(time, status) ~ age, data=cos)

If that code is in a function anywhere (package or not), cos will be a 
local variable created there in the evaluation environment created when 
you evaluate the function.  If you execute it at the command line, 
you'll create a variable called "cos" in the global environment.  Local 
variables come ahead of the 3 places I listed.  (This is why Luke's 
article is good:  it doesn't oversimplify.)

There's one other twist.  Even with cos being a local variable, 
cos(theta) would find base::cos, because the evaluator knows it is 
looking for a function (since it's a function call) and will skip over 
the local dataframe named cos.

Duncan Murdoch

> Terry T.
> On 11/06/2015 07:51 AM, Duncan Murdoch wrote:
>> On 06/11/2015 7:36 AM, Therneau, Terry M., Ph.D. wrote:
>>> I am currently puzzled by a seach path behavior.  I have a library of a dozen routines
>>> getlabs(), getssn(), getecg(), ... that interface to local repositories and pull back
>>> patient information.  All have a the first 6 arguments in common, and immediately call a
>>> second routine to do initial processing of these 6.  The functions "joe" and "fred" below
>>> capture the relevant portion of them.
>>>      My puzzle is this: the last test in the "test" file works fine if these routines are
>>> sourced and executed at the command line, it fails if the routines are bundled up and
>>> loaded as a library. That test is motivated by a user who called his data set "t", and
>>> ended up with a match to base:::t instead of his data, resulting in a strange error
>>> message out of model.frame  --- you can always count on the users!  (There are a few
>>> hundred.)
>>>       I'm attempting to be careful with envr and enclos arguments -- how does base end up
>>> earlier in the search path?   Perhaps this is clearly stated in the docs and just not
>>> clear to me?  A working solution to the dilemma is of course more than welcome.
>> I haven't followed through all the details in fred(), but I can answer the last question.
>> In package code, the search order is:
>> - the package environment
>> - the imports to the package (with base being an implicit import)
>> - the global environment and the rest of the search list.
>> In code sourced to the global environment, only the third of these is searched.  Since
>> base is in the second one, it is found first in the package version.
>> Duncan Murdoch

More information about the R-devel mailing list