如何在现有环境中添加功能

时间:2012-01-25 12:15:25

标签: r

是否可以使用env()替代命名空间,如何在向其添加函数之前检查环境是否存在?

这与这个问题和布兰登的建议有关 How to organize large R programs? 我理解Dirk在这个问题上的观点,但是对于开发来说,将函数放入包中有时是不切实际的。

编辑:这个想法是模仿文件中的命名空间,因此能够独立加载不同的文件。如果先前已加载文件,则不需要创建环境,只需添加到。

感谢您的想法

编辑:因此,下面的代码可能相当于其他语言中的命名空间: -

 # how to use environment as namespaces

# file 1

# equivalent of 'namespace e' if (!(exists("e") && is.environment(e))) {   e <- new.env(parent=baseenv()) }

e$f1 <- function(x) {1}


# file 2
# equivalent of 'namespace e' if (!(exists("e") && is.environment(e))) {   e <- new.env(parent=baseenv()) }

e$f2 <- function(x) {2}

3 个答案:

答案 0 :(得分:6)

是的,你可以在大多数情况下。每个函数都有一个环境,它就是寻找其他函数和全局变量的地方。通过使用您自己的环境,您可以完全控制它。

通常,函数也分配到环境中(通过将它们分配给名称),通常这两个环境是相同的 - 但并非总是如此。在包中,命名空间环境用于两者,但是搜索路径上的(不同)包环境也定义了相同的(导出的)功能。所以环境不同。

# this will ensure only stats and packages later on the search list are searched for
# functions from your code (similar to import in a package)
e <- new.env(parent=as.environment("package:stats"))

# simple alternative if you want access to everything
# e <- new.env(parent=globalenv())

# Make all functions in "myfile.R" have e as environment
source("myfile.R", local=e)

# Or change an existing function to have a new environment:
e$myfunc <- function(x) sin(x)
environment(e$myfunc) <- e

# Alternative one-liner:
e$myfunc <- local(function(x) sin(x), e)

# Attach it if you want to be able to call them as usual.
# Note that this creates a new environment "myenv".
attach(e, name="myenv")

# remove all temp objects
rm(list=ls())

# and try your new function:
myfunc(1:3)

# Detach when it's time to clean up or reattach an updated version...
detach("myfile")

在上面的示例中,e对应于命名空间,附加的“myenv”对应于包环境(如搜索路径上的“package:stats”)。

答案 1 :(得分:4)

命名空间环境,因此您可以使用完全相同的机制。由于R使用词法作用域,因此环境的父级定义了函数将看到的内容(即自由变量如何绑定)。与命名空间完全一样,您可以附加环境并查找它们。

因此,要创建一个新的“手动命名空间”,您可以使用类似

的内容
e <- new.env(parent=baseenv())
# use local(), sys.source(), source() or e$foo <- assignment to populate it, e.g.
local({
  f <- function() { ... }
  #...
}, e)
attach(e, name = "mySuperNamespace")

现在它像命名空间一样被加载和附加 - 所以你可以像命名空间一样使用f。命名空间使用另一个父环境来解析导入 - 如果您愿意,也可以这样做。如果您需要检查您的酷环境,请查看搜索路径,例如"mySuperNamespace" %in% search()。如果您需要实际环境,请使用as.environment("mySuperNamespace")

答案 2 :(得分:2)

您可以按照与其他变量相同的方式检查环境是否存在。

e <- new.env()
exists("e") && is.environment(e)