简体   繁体   English

在 R 的 eval 函数中访问当前环境

[英]Accessing current environment in R's eval function

According to this post , environment() function is the function to call a current environment.根据这篇文章environment()函数是调用当前环境的函数。

However, I found that at least that is not the case in eval function, with following examples.但是,我发现至少在eval函数中不是这种情况,下面是示例。

.env <- new.env()
.env$info$progress <- 3
.expr <- "environment()$info$progress <- 5"
eval(parse(text = .expr), envir = .env, enclos = .env)

> invalid (NULL) left side of assignment

I also tried assign function, but it does not work either我也试过assign功能,但它也不起作用

.env <- new.env()
.env$info$progress <- 3
.expr <- "assign(info$progress, 11, envir = environment())"
eval(parse(text = .expr), envir = .env, enclos = .env)

> Error in assign(info$progress, 11, envir = environment()) :
> invalid first argument

So environment function failed to find current environment in eval .因此environment函数无法在eval找到当前环境。

I would appreciate if anyone lets me know how to access current environment in above examples or how to move-around this issue in eval .如果有人让我知道如何在上述示例中访问当前环境或如何在eval解决此问题,我将不胜感激。

environment() does what you think it does. environment()做你认为它做的事情。 The issue is with assigning directly to the result of a function call.问题在于直接分配给函数调用的结果。

> new.env()$info$progress <- 3
Error in new.env()$info$progress <- 3 : 
  invalid (NULL) left side of assignment
> .env <- new.env()
> .env$info$progress <- 3
> evalq(identical(environment(), .env), envir = .env)
[1] TRUE
> evalq({ e <- environment(); e$info$progress <- 5 }, envir = .env)
> .env$info
$progress
[1] 5

The goal (which I thought was access to a defined environment) can be accomplished by considering the fact that no call to environment is needed.考虑到不需要调用environment这一事实,可以实现目标(我认为是访问定义的环境)。 That function with a NULL argument doesn't retrieve anything useful.带有 NULL 参数的函数不会检索任何有用的信息。 The .env object is an environment, so the assignment should just be into it: .env对象是一个环境,所以赋值应该放在它里面:

.env <- new.env()

.env$info$progres <- 3
.expr <- ".env$info$progres <- 5"
eval(parse(text = .expr) )
#------------
> ls(envir=.env)
[1] "info"
> ?get
> get("info", envir=.env)
$progres
[1] 5

The environment assignment operation is supposed to put values into the environment of functions.环境分配操作应该将值放入函数的环境中。 I think it's probably undefined when you make an assignment into an unbound environment.我认为当您将任务分配到未绑定的环境中时,它可能是未定义的。 I would not have thought that environment()$info$progres <- 5 would have succeeded in placing a value into .env since the target of environment(.)<- was NULL .我不会想到environment()$info$progres <- 5会成功地将一个值放入.env因为environment(.)<-的目标是NULL

Responding to your comment: I'm not sure what was meant by " a current environment".在回答您的评论:我不知道什么是“当前环境”的意思。 There is "the current environment" and the .env -environment was not that environment (nor was it ever that environment, even for an instant).有“当前环境”,而.env -environment 不是那个环境(也不是那个环境,即使是瞬间)。 Creating an environment with new.env does not make it the current environment.使用new.env创建环境不会使其成为当前环境。 It only creates an environment which allows you to store or retrieve objects in it by referencing its name.它只创建一个环境,允许您通过引用其名称来存储或检索其中的对象。

 .env <- new.env()
 environment()
#<environment: R_GlobalEnv>

It isn't even on the search path.它甚至不在搜索路径上。 It's kind of "on the sidelines" waiting to be referenced.这是一种等待被引用的“旁观者”。

> search()
 [1] ".GlobalEnv"         "package:acs"        "package:XML"        "package:acepack"    "package:abind"     
 [6] "package:downloader" "package:forcats"    "package:stringr"    "package:dplyr"      "package:purrr"     
[11] "package:readr"      "package:tidyr"      "package:tibble"     "package:tidyverse"  "tools:RGUI"        
[16] "package:grDevices"  "package:utils"      "package:datasets"   "package:graphics"   "package:rms"       
[21] "package:SparseM"    "package:Hmisc"      "package:ggplot2"    "package:Formula"    "package:stats"     
[26] "package:survival"   "package:sos"        "package:brew"       "package:lattice"    "package:methods"   
[31] "Autoloads"          "package:base"      
> ls(envir=.env)
[1] "info"

I find myself wondering if the goal was to use a more object-oriented style, and if so would recommend looking at the ?R6 help page and the section in the R Language Definition entitled: "5 Object-oriented programming".我发现自己想知道目标是否是使用更面向对象的风格,如果是这样,建议查看?R6帮助页面和 R 语言定义中标题为“5 面向对象的编程”的部分。

After navigating through the help pages looking at the code for getAnywhere , ?find , ?ls , ?objects , I found a particular use of apropos that you might find interesting:在浏览帮助页面并查看getAnywhere?find?ls?objects ,我发现了一个您可能会感兴趣的apropos的特殊用法:

apropos("\\.", mode="environment")
[1] ".AutoloadEnv"  ".BaseNamespaceEnv" ".env" ".GenericArgsEnv" ".GlobalEnv" 
[6] ".userHooksEnv" 

If you use:如果您使用:

  apropos("." , mode="environment")`

..., constructed with the most generic pattern possible, you will also find the 100 or so ggproto-environments defined by ggplot2-functions, assuming you have that package loaded. ...,使用最通用的模式构建,您还将找到由 ggplot2-functions 定义的 100 个左右的 ggproto 环境,假设您加载了该包。 I think Hadley's "Advanced Programming" may have more on this topic of interest because he defines a "environment list" class and functions to manipulate them.我认为 Hadley 的“高级编程”可能对这个话题有更多的兴趣,因为他定义了一个“环境列表”类和操作它们的函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM