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

时间:2018-04-22 06:58:34

标签: r

根据this postenvironment()函数是调用当前环境的函数。

但是,我发现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

我也试过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

因此environment函数无法在eval中找到当前环境。

如果有人让我知道如何访问上述示例中的当前环境或如何在eval中解决此问题,我将不胜感激。

2 个答案:

答案 0 :(得分:1)

environment() 做你认为它做的事情。问题在于直接分配给函数调用的结果。

> 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

答案 1 :(得分:0)

目标(我认为是访问已定义的环境)可以通过考虑不需要调用environment这一事实来实现。具有NULL参数的该函数不会检索任何有用的内容。 .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

环境分配操作应该将值放入函数环境中。我认为当您在未绑定的环境中进行分配时,它可能是未定义的。我不会认为environment()$info$progres <- 5会成功将值放入.env,因为environment(.)<-的目标是NULL

回应您的评论:我不确定“ a 当前环境”是什么意思。有“当前环境”和.env - 环境不是那个环境(也不是那个环境,即使是瞬间)。使用new.env创建环境并不会使其成为当前环境。它只创建一个环境,允许您通过引用其名称来存储或检索其中的对象。

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

它甚至不在搜索路径上。这种“在场外”等待被引用。

> 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"

我发现自己想知道目标是否使用更面向对象的样式,如果是这样,建议查看?R6帮助页面和R语言定义中标题为“5面向对象”的部分编程”。

浏览帮助页面,查看getAnywhere?find?ls?objects的代码后,我发现了apropos的特定用途你可能会觉得有趣:

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

如果您使用:

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

...,使用最通用的模式构建,您还可以找到由ggplot2-functions定义的100个左右的ggproto环境,假设您已加载该包。我认为Hadley的“高级编程”可能在这个感兴趣的主题上有更多,因为他定义了一个“环境列表”类和操作它们的函数。