首页 > 解决方案 > R - 在函数中创建环境并在任何地方访问其变量

问题描述

我正在尝试创建和使用环境来分配变量,代码中的任何函数都可以访问这些变量,包括在函数中运行的函数。

但是,即使我创建了这样的环境并将其放在搜索路径上,也找不到它的对象。来自其他环境(例如库)的对象并非如此。

每次我想使用这样的对象时,我总是可以分配和获取值,但是搜索路径的功能不是递归地在其环境中查找对象吗?

这是一个可重现的代码示例:

First.function = function(){
  Working_env = new.env(parent = .GlobalEnv) 
  attach(what = Working_env, pos = 2)
  
  Called.from.First()
}

Called.from.First = function(){
  print(search())
  
  assign(x = "global.a", value = 1, envir = Working_env) # It doesn't recognized 'Working_env, although it is on the search path
}

First.function()
# [1] ".GlobalEnv"        "Working_env"      "package:base"

# Error in assign(x = "global.a", value = 1, envir = Working_env) : 
# object 'Working_env' not found

更新

谢谢@MrFlick。我尝试了你的建议,但我一直遇到同样的问题。

我要做的是创建一个环境,无论什么环境处于活动状态(在函数内、从函数调用的函数内等),都可以在其中找到对象。这就是加载库时会发生的情况,我认为当您对同一对象(例如,相同的列表和 data.frames)进行多项操作时,它可能很有用并简化代码。

此代码有效:

First.function = function(){
  assign(x = "Working_env", value = new.env(), envir = .GlobalEnv)  
  
  Called.from.First()
  
  print(Working_env$global.a)
}

Called.from.First = function(){
  assign(x = "global.a", value = 1, envir = Working_env)
}

Second = function(){
  print(Working_env$global.a)
}

First.function()
# [1] 1

Second()
# [1] 1

但是这段代码不起作用:

First.function = function(){
  assign(x = "Working_env", value = new.env(), envir = .GlobalEnv)
  attach(what = Working_env, pos = 2)  
  
  Called.from.First()
  
  print(global.a)
}

Called.from.First = function(){
  print(search()) # Show that «Working_env' is in the search directory
  
  assign(x = "global.a", value = 1, envir = Working_env) # Recognizes 'Working_env' in the .GlobalEnv
  
  print(ls(envir = Working_env))  # Shows that the variable was created in the environment
}

First.function()
# [1] ".GlobalEnv"        "Working_env"      "package:base"

# [1] "global.a"

# Error in print(global.a) : object 'global.a' not found

有没有办法我可以创建一个环境,将它放在搜索路径上,以便它的对象可以被任何功能找到和操作(而不总是指出环境)?这类似于库加载的函数和数据集所发生的情况。这也是 .GlobalEnv (或创建函数的环境)和 '<<-' (范围分配)运算符发生的情况。

我意识到似乎有一些技巧和解决方案这样做(如使用 devtools:load_all() ),但我想必须有一个更简单的解决方案。

标签: renvironment

解决方案


推荐阅读