我试图用'inner_func'中的值覆盖'outer_func'中的变量a。我不希望它在函数'outer_func'之外生成变量。
inner_func <- function(){
a <<- 30
}
outer_func <- function(){
a <- 10
inner_func()
print(a)
}
outer_func()
输出为10,但应为30。
答案 0 :(得分:2)
您可以将assign
与parent.frame()
一起使用(parent.frame()
是外部函数的环境,在这种情况下parent.frame(2)
是全局环境):
inner_func <- function(){
assign("a", 30, envir = parent.frame())
}
outer_func <- function(){
a <- 10
inner_func()
print(a)
}
outer_func()
但是要小心,因为使用类似的副作用会使代码复杂得多,并且通常是不可取的。
答案 1 :(得分:1)
这里有3个替代方案。 (1)对inner_func
不做任何更改,而(3)对outer_func
不做任何更改。
1)复制并重置inner_func的环境在inner_func
中复制outer_func
的副本,并将当前环境强制转换为副本。 inner_func
不会进行任何更改,outer_func
仅添加了一行,并且两者都可以复制并更改其环境。
outer_func <- function() {
a <- 10
environment(inner_func) <- environment()
inner_func()
print(a)
}
outer_func()
## [1] 30
2)将inner_func嵌套在external_func 中,另一种方法是将inner_func
嵌套在outer_func
内。
outer_func <- function() {
inner_func <- function() {
a <<- 30
}
a <- 10
inner_func()
print(a)
}
outer_func()
## [1] 30
3)通过arg传递环境另一种方法是通过参数将a
所在的环境传递给inner_func
。通过将父框架设置为该参数的默认值,我们可以避免对outer_func
进行任何更改。
inner_func <- function(envir = parent.frame()) {
envir$a <- 30
}
outer_func <- function() {
a <- 10
inner_func()
print(a)
}
outer_func()
## [1] 30
如果a
定义为outer_func
,则可以扩展其中的任何一个以设置特定的矩阵元素。
a <- matrix(1:4, 2)
在(1)和(2)中修改inner_func
以使用,例如:
a[1,1] <<- 30
和(3)中的示例在inner_func
中使用:
envir$a[1,1] <- 30
答案 2 :(得分:1)
其他答案集中在如何使outer_func
和inner_func
表现得像您期望的那样。我将尝试说明为什么他们不这样做。
如果重新定义inner_func
以打印其父级环境,您会发现它不是调用方的环境,而是全局环境。
inner_func <- function(){
print(parent.env(environment()))
a <<- 30
}
现在调用outer_func
,发现它正在尝试在该环境中而不是在a
的环境中查找变量outer_func
。
outer_func()
#<environment: R_GlobalEnv>
#[1] 10
当您打印a
时,在调用outer_func
之后,它具有预期的值。
a
#[1] 30
函数inner_func
找不到a
,因此在GlobalEnv
中创建了它。
将以上内容与以下内容进行比较。 inner_func
在outer_func
中定义。现在,分配<<-
找到a
并更改其值。
outer_func2 <- function(){
inner_func <- function(){
print(parent.env(environment()))
a <<- 30
}
a <- 10
inner_func()
print(a)
}
rm(a)
outer_func2()
#<environment: 0xdd06e18>
#[1] 30
但是由于outer_func2
未分配其值,因此a
中不存在GlobalEnv
。仅在outer_func
(它存在的唯一位置)中进行了更改。
a
#Error: object 'a' not found