10
library(rlang)
myquo <- quo((Temp - 32) / 1.8)
eval_tidy(myquo, data = as_data_mask(datasets::airquality)) # works
e <- as_env(datasets::airquality, parent = global_env())
eval_tidy(myquo, data = as_data_mask(list(), parent = e))   # error

I expected Temp to be found in e. What am I doing wrong?

PS: I have R version 3.5.0 and tested this with both latest CRAN and GitHub version of {rlang}.

F. Privé
  • 11,423
  • 2
  • 27
  • 78
  • 1
    This is interesting because both `get("Temp", as_data_mask(list(), parent = e))` and `get("Temp", as_data_mask(list(Temp=1), parent = e))` work as expected. It probably makes more sense to post this to the rlang issues page though: https://github.com/r-lib/rlang/issues – MrFlick Aug 13 '18 at 21:42
  • I'm new at using {rlang} so I've no idea if the issue comes from me or from {rlang}. – F. Privé Aug 13 '18 at 21:44
  • Interesting that `R> e ` & `as_data_mask(list(), parent = e) ` returned different results – Tung Aug 13 '18 at 23:44
  • 1
    @Tung is that interesting though? That's basically like `new.env(parent=globalenv())`, right? You would expect that to return something different. There needs to be a new object to hold the parent information. – MrFlick Aug 14 '18 at 01:33
  • 1
    @Tung I think this is normal because `e` is the parent, not the environment itself. See `env_parents(as_data_mask(list(), parent = e))`. – F. Privé Aug 14 '18 at 04:53
  • #TIL. Thanks guys. – Tung Aug 14 '18 at 05:19
  • 1
    I opened [an issue](https://github.com/r-lib/rlang/issues/571) on {rlang}'s repo. – F. Privé Aug 14 '18 at 05:19

1 Answers1

1

I think the documentation might have been updated since the question was asked, but for new visitors, the relevant part of the rlang documentation for as_data_mask is:

parent Soft-deprecated. This argument no longer has any effect. The parent of the data mask is determined from either:

  • The env argument of eval_tidy()
  • Quosure environments when applicable

So in the case of eval_tidy(myquo, data = as_data_mask(list(), parent = e)) the env of eval_tidy and the quosure env on myquo are both the global env, and the data mask itself is empty, hence why Temp is not found.

eval_tidy(myquo, data = as_data_mask(datasets::airquality)) 

works but has an unnecessary call in it, since the data argumnet of eval_tidy will convert a data.frame to a data mask anyway, so the easiest way would be.

eval_tidy(myquo, data = datasets::airquality) 

On the other hand, if you really want to specify the environment explicitly in eval_tidy, you could use expr instead of quo

myexpr <- expr((Temp - 32) / 1.8)
eval_tidy(myexpr, data = as_data_mask(list(), parent = e)) # still fails since parent is overridden 
eval_tidy(myexpr, data = list(), env = e) # works since there's no quosure env to override env
Tom Greenwood
  • 1,502
  • 14
  • 17