gpt4 book ai didi

r - 如何将文件源放入全局环境中的列表中

转载 作者:行者123 更新时间:2023-12-04 14:03:41 25 4
gpt4 key购买 nike

我有以下要求:我在 config.R 中定义了一个变量和函数列表文件:

# config.R
x <- 1
foo <- function(y) {
2
}
z <- x + 1

我希望以上内容在 .Globalenv 中定义的列表中“获取”我有办法通过创建本地环境来做到这一点:

source_in_list <- function(path) {
e <- new.env()
source(path, local = e)
return(as.list(e))
}

p <- source_in_list("config.R")
p
$x
[1] 1

$z
[1] 2

$foo
function(y) {
2
}
<environment: 0x2f99d90>

我的问题是 foo 链接到 <environment: 0x2f99d90> ,这意味着如果我要重新定义 foo.Globalenv p$foo不会受到影响,这不是我想要的。本质上,我想做的就好像我是:

  • .Globalenv 中创建 p
  • 执行每一行within p

所以结果会是这样的:

p
$x
[1] 1

$z
[1] 2

$foo
function(y) {
2
}

我该怎么做?

编辑:

我意识到我想要的是在 globalenv() 中定义源文件中的函数,其余部分在列表中

source_in_list <- function(path) {                                                                                                                                                                                                             
e <- new.env()
source(path, local = e)
# types
is_fun <- sapply(e, FUN = function(x) inherits(x, "function"))
# define functions from e into globalenv
if(any(is_fun)) {
for(fun_name in names(which(is_fun))) {
# assign in globalenv
assign(x = fun_name, value = eval(parse(text = deparse(get(fun_name, envir = e))), envir = globalenv()), envir = globalenv())
# remove from local env
rm(list = fun_name, envir = e)
}
}
return(as.list(e))
}
p1 <- source_in_list("config.R")

p1
$x
[1] 1

$z
[1] 2

foo
function (y)
{
2
}
>

最佳答案

我认为你有一个误解:if foo存储在您的列表中 p , 然后重新定义 foo.Globalenv不会有任何影响。这些将是单独的对象。

与函数关联的环境的目的是告诉 R 到哪里寻找函数中使用的非局部变量。您的原始版本最终将包含您采购的所有内容的两份副本,一份在列表中,一份在您创建的本地环境中。如果foo引用x , 它会在本地环境中看到那个。例如,查看对代码的更改,其中 foo()返回 x :

# config.R
x <- 1
foo <- function() {
x
}
z <- x + 1

然后

source_in_list <- function(path) {
e <- new.env()
source(path, local = e)
return(as.list(e))
}

p <- source_in_list("config.R")
x <- 42 # Set a global variable x
p$foo()
# [1] 1 # It is ignored

p$x <- 123 # Set x in p
p$foo()
# [1] 1 # It is ignored

您可能不想要所有内容的两份副本。但是不清楚你想做什么是可能的。列表不能充当函数的环境,因此无法生成 p$x成为内部引用的目标 foo .

我建议您不要返回列表,而只需返回您创建的本地环境。然后事情就会如你所愿:

source_to_local <- function(path) {
e <- new.env()
source(path, local = e)
return(e)
}

e <- source_to_local("config.R")
x <- 42 # set a global
e$foo()
[1] 1 # it is ignored

e$x <- 123 # set x in e
e$foo()
[1] 123 # it responds

返回环境的主要缺点是它们不像列表那样打印,但您可能会编写一个函数来打印环境并使其中的所有内容可见。

关于r - 如何将文件源放入全局环境中的列表中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69233358/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com