您必须在 R 中定义函数的环境吗?
Do you have to define the environment of a function in R?
您是否必须在 R 中显式定义自定义函数的环境,还是在创建函数时自动 "created"(定义?)?
我想知道创建一个函数是否会自动在所述函数内创建一个环境,或者是否需要显式创建环境。如果前者为真(即环境是自动创建的),我该如何明确引用它?
我必须首先为所述函数创建一个新环境(即,通过使用 new.env
分配一个新环境)还是我可以简单地使用一些其他语法(可能类似于“current.env()
”) ?
我能想出的唯一使用它的简单示例是函数内部的 assign
函数。
function(a,b) {
assign(paste(a,b,sep='.'), 'help me', envir = ONLY CURRENT FUNCTION)
}
不要在作业中提及环境。
foo = function(a,b){
assign(paste(a,b,sep="."),99)
return(hey.you) # note this is hard coded here...
}
没有什么叫hey.you
:
> ls()
[1] "foo"
我调用 foo
,它创建了一个 hey.you
和 returns 它的值:
> foo("hey","you")
[1] 99
但不会弄乱我的环境,因为它是在函数的环境中创建的:
> ls()
[1] "foo"
因为这是默认值。
?assign
pos: where to do the assignment. By default, assigns into the
current environment. See ‘Details’ for other possibilities.
如果您必须明确提及它,而您没有必要,那就不要,除非您能给我们一个 真正好的 为什么您必须这样做的理由,然后复制 assign 的作用:
> foo = function(a,b){assign(paste(a,b,sep="."),99,envir=as.environment(-1));ls()}
> foo("fnord","fnord")
[1] "a" "b" "fnord.fnord"
或复制其他人在这里所说的话:
> foo = function(a,b){assign(paste(a,b,sep="."),99,envir=environment());ls()}
> foo("bubble","gum")
[1] "a" "b" "bubble.gum"
当前环境由environment()
return编辑:
> environment()
<environment: R_GlobalEnv>
> foo <- function() environment()
> foo()
<environment: 0x1391b88>
> foo()
<environment: 0x1391f08>
> foo()
<environment: 0x1392288>
> foo()
<environment: 0x13916a0>
请注意,对 foo()
的每次调用都有不同的环境,因为您正在考虑的环境只会在调用函数时创建。
要获取调用函数的封闭框架,请使用 parent.frame()
:
> bar <- function() parent.frame()
> bar()
<environment: R_GlobalEnv>
因为 bar()
是从我的工作区调用的,所以全局环境是 returned。但是,如果我们从另一个函数内部调用 bar()
,我们会得到 that 函数的环境,因为它现在是调用环境:
> foobar <- function() { print(environment()); bar() }
> foobar()
<environment: 0x74a7d68>
<environment: 0x74a7d68>
如果我们查看您的 assign()
示例,如果您想要当前环境,则不必告诉它使用哪个环境,因为这是默认设置的工作方式。但是,如果您想明确说明这一点,您可以使用:
foo <- function(x) {
assign("y", x, envir = environment())
y # return(y) to show it is assigned `x`
}
这给出了
> foo(20)
[1] 20
> foo(10)
[1] 10
> foo("a")
[1] "a"
如果想在父框架中赋值,只需要传envir = parent.frame()
:
foo <- function(x) {
assign("y", x, envir = parent.frame())
"not returning `y`" # return something else
}
这给出了
> ls()
[1] "bar" "foo" "foobar"
> foo(20)
[1] "not returning `y`"
> ls()
[1] "bar" "foo" "foobar" "y"
> y
[1] 20
即使我们没有 return y
,assign()
在我们指定的环境中创建了 y
。
需要强调的是,很少有人会像这样 assign()
分配到其他环境中。一个主要原因是现在你的函数有副作用,而 R 是一种函数式语言,通过让函数接受输入和 return 输出而不影响任何其他东西,更容易推断代码的工作方式。因此你更喜欢
foo1 <- function(x) {
y <- x
y
}
y <- foo1(x)
超过
foo2 <- function(x, varname) {
assign(varname, x, envir = parent.frame())
invisible()
}
foo2(x, "y")
因为我知道调用 foo1()
没有副作用,它只是接受一些输入并 return 输出。这有点做作,因为您选择了 assign()
但这将广泛适用。这也是复杂列表或其他类型的对象从许多 R 函数中 return 编辑的原因,尤其是那些适合模型的函数。
您是否必须在 R 中显式定义自定义函数的环境,还是在创建函数时自动 "created"(定义?)?
我想知道创建一个函数是否会自动在所述函数内创建一个环境,或者是否需要显式创建环境。如果前者为真(即环境是自动创建的),我该如何明确引用它?
我必须首先为所述函数创建一个新环境(即,通过使用 new.env
分配一个新环境)还是我可以简单地使用一些其他语法(可能类似于“current.env()
”) ?
我能想出的唯一使用它的简单示例是函数内部的 assign
函数。
function(a,b) {
assign(paste(a,b,sep='.'), 'help me', envir = ONLY CURRENT FUNCTION)
}
不要在作业中提及环境。
foo = function(a,b){
assign(paste(a,b,sep="."),99)
return(hey.you) # note this is hard coded here...
}
没有什么叫hey.you
:
> ls()
[1] "foo"
我调用 foo
,它创建了一个 hey.you
和 returns 它的值:
> foo("hey","you")
[1] 99
但不会弄乱我的环境,因为它是在函数的环境中创建的:
> ls()
[1] "foo"
因为这是默认值。
?assign
pos: where to do the assignment. By default, assigns into the
current environment. See ‘Details’ for other possibilities.
如果您必须明确提及它,而您没有必要,那就不要,除非您能给我们一个 真正好的 为什么您必须这样做的理由,然后复制 assign 的作用:
> foo = function(a,b){assign(paste(a,b,sep="."),99,envir=as.environment(-1));ls()}
> foo("fnord","fnord")
[1] "a" "b" "fnord.fnord"
或复制其他人在这里所说的话:
> foo = function(a,b){assign(paste(a,b,sep="."),99,envir=environment());ls()}
> foo("bubble","gum")
[1] "a" "b" "bubble.gum"
当前环境由environment()
return编辑:
> environment()
<environment: R_GlobalEnv>
> foo <- function() environment()
> foo()
<environment: 0x1391b88>
> foo()
<environment: 0x1391f08>
> foo()
<environment: 0x1392288>
> foo()
<environment: 0x13916a0>
请注意,对 foo()
的每次调用都有不同的环境,因为您正在考虑的环境只会在调用函数时创建。
要获取调用函数的封闭框架,请使用 parent.frame()
:
> bar <- function() parent.frame()
> bar()
<environment: R_GlobalEnv>
因为 bar()
是从我的工作区调用的,所以全局环境是 returned。但是,如果我们从另一个函数内部调用 bar()
,我们会得到 that 函数的环境,因为它现在是调用环境:
> foobar <- function() { print(environment()); bar() }
> foobar()
<environment: 0x74a7d68>
<environment: 0x74a7d68>
如果我们查看您的 assign()
示例,如果您想要当前环境,则不必告诉它使用哪个环境,因为这是默认设置的工作方式。但是,如果您想明确说明这一点,您可以使用:
foo <- function(x) {
assign("y", x, envir = environment())
y # return(y) to show it is assigned `x`
}
这给出了
> foo(20)
[1] 20
> foo(10)
[1] 10
> foo("a")
[1] "a"
如果想在父框架中赋值,只需要传envir = parent.frame()
:
foo <- function(x) {
assign("y", x, envir = parent.frame())
"not returning `y`" # return something else
}
这给出了
> ls()
[1] "bar" "foo" "foobar"
> foo(20)
[1] "not returning `y`"
> ls()
[1] "bar" "foo" "foobar" "y"
> y
[1] 20
即使我们没有 return y
,assign()
在我们指定的环境中创建了 y
。
需要强调的是,很少有人会像这样 assign()
分配到其他环境中。一个主要原因是现在你的函数有副作用,而 R 是一种函数式语言,通过让函数接受输入和 return 输出而不影响任何其他东西,更容易推断代码的工作方式。因此你更喜欢
foo1 <- function(x) {
y <- x
y
}
y <- foo1(x)
超过
foo2 <- function(x, varname) {
assign(varname, x, envir = parent.frame())
invisible()
}
foo2(x, "y")
因为我知道调用 foo1()
没有副作用,它只是接受一些输入并 return 输出。这有点做作,因为您选择了 assign()
但这将广泛适用。这也是复杂列表或其他类型的对象从许多 R 函数中 return 编辑的原因,尤其是那些适合模型的函数。