[英]Do you have to define the environment of a function in R?
您是否必須在R中顯式定義自定義函數的環境,還是在創建函數時自動“創建”(定義?)?
我想知道是否創建函數會自動在所述函數內創建環境,或者是否需要顯式創建環境。 如果前者是正確的(即,環境是自動創建的),我如何顯式引用它?
我必須首先為上述函數創建一個新環境(即,通過使用new.env
分配一個新環境)還是可以簡單地使用其他語法(例如“ current.env()
類的東西current.env()
”?
我可以使用的唯一簡單示例就是在函數內部assign
函數。
function(a,b) {
assign(paste(a,b,sep='.'), 'help me', envir = ONLY CURRENT FUNCTION)
}
當前環境由environment()
返回:
> 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()
時,將返回全局環境。 但是,如果我們從另一個函數內部調用bar()
,則會得到該函數的環境,因為它現在是調用環境:
> 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
即使我們沒有返回y
, assign()
在我們指定的環境中也創建了y
。
需要強調的是,盡管很少有人會像這樣進行assign()
分配到其他環境,這一點很重要。 造成這種情況的主要原因是,現在您的函數具有副作用,R是一種函數語言,在這種語言中,通過使函數接受輸入和返回輸出而又不影響任何其他函數,可以更容易地推斷代碼的工作方式。 因此,您寧願
foo1 <- function(x) {
y <- x
y
}
y <- foo1(x)
過度
foo2 <- function(x, varname) {
assign(varname, x, envir = parent.frame())
invisible()
}
foo2(x, "y")
因為我知道調用foo1()
沒有副作用,所以它只是接受一些輸入並返回輸出。 這有點人為,因為您選擇了assign()
但這將廣泛適用。 這也是為什么許多R函數(尤其是適合模型的R函數)返回復雜列表或其他類型的對象的原因。
不要在分配中提及環境。
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
並返回其值:
> 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"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.