R 中从函数到全局环境的绑定值
Binding values from function to global environment in R
我无法理解如何将函数内的值绑定到函数外的环境。下面显示了一个基本示例,我似乎无法解决函数的最后一部分:
number <- data.frame()
how_many_fruits <- function() {
answer <- as.integer(readline(prompt="How Many?: "))
globalenv()$number <- rbind(globalenv()$number, answer)
}
本质上,我想在开始时有一个名为number
的空数据框,每次how_many_fruits()
是运行,我希望输入附加到底部number
数据框。
您可以使用 <<-
运算符:
number <- data.frame()
how_many_fruits <- function() {
answer <- as.integer(readline(prompt="How Many?: "))
number <<- rbind(number, answer)
}
但是,我想知道您对该程序的目标是什么。函数不应该像您那样在全局环境中使用变量。如果有人想使用那个函数,但调用变量 num
而不是 number
,会发生什么?该功能在那种情况下不起作用。所以我建议您改为执行以下操作:
how_many_fruits <- function(num) {
answer <- as.integer(readline(prompt="How Many?: "))
new_num <- rbind(num, answer)
return (new_num)
}
number <- data.frame()
number <- how_many_fruits(number)
这就是一个函数应该如何工作:它接受输入(此处称为 num
)并 returns 输出(此处称为 new_num
)。请注意输入和输出的名称 inside 函数不必与您在函数 outside 中使用的变量名称相同。当您调用 how_many_fruits(number)
时,number
的内容存储在 num
中,该函数仅适用于后者。当您执行 number <- how_many_fruits(number)
时,作为 how_many_fruits(number)
结果返回的任何内容都存储在 number
.
中
直接从函数中修改全局环境不是一个好主意。通常,只 return 一个值并让用户将其附加到需要的地方是一个更好的主意。 (正如 Stibu 解释的那样)。
但是,您也可以使用嵌套环境,如下面对官方 R 语言定义中的示例进行的修改:
fruitscollector <- function(){
fruitslist <- NULL
function(){
answer <- as.integer(readline(prompt="How Many?: "))
fruitslist <<- c(fruitslist, answer)
fruitslist
}
}
所以当您第一次初始化一个 "fruitscollector" 时,它 return 只是一个可以收集值的函数。
foo <- fruitscollector()
现在每次使用 foo
时,都会将一个值添加到集合中(整个集合是 returned):
foo()
foo()
# etc
fruitslist
存储在 foo
的父环境中,因此不在您可能会意外删除它的全局环境中。
编辑
一个更一般的想法是创建一个对象(有点类似于 OOP 中所谓的 "object"),函数作为方法,例如
collector <- function(){
stack <- NULL
list(
add = function(x) stack<<-c(stack, x),
get = function() stack,
empty = function() stack <<- NULL
)
}
现在 add
方法将添加到堆栈,get
方法将 return 整个堆栈,而 empty
方法将清空它。
foo <- collector() # initialize
foo$get() # NULL
foo$add(1) # add 1 to the stack
foo$get() # 1
foo$add(3) # add 3 to the stack
foo$get() # 1 3
foo$add(1:5) # etc...
我无法理解如何将函数内的值绑定到函数外的环境。下面显示了一个基本示例,我似乎无法解决函数的最后一部分:
number <- data.frame()
how_many_fruits <- function() {
answer <- as.integer(readline(prompt="How Many?: "))
globalenv()$number <- rbind(globalenv()$number, answer)
}
本质上,我想在开始时有一个名为number
的空数据框,每次how_many_fruits()
是运行,我希望输入附加到底部number
数据框。
您可以使用 <<-
运算符:
number <- data.frame()
how_many_fruits <- function() {
answer <- as.integer(readline(prompt="How Many?: "))
number <<- rbind(number, answer)
}
但是,我想知道您对该程序的目标是什么。函数不应该像您那样在全局环境中使用变量。如果有人想使用那个函数,但调用变量 num
而不是 number
,会发生什么?该功能在那种情况下不起作用。所以我建议您改为执行以下操作:
how_many_fruits <- function(num) {
answer <- as.integer(readline(prompt="How Many?: "))
new_num <- rbind(num, answer)
return (new_num)
}
number <- data.frame()
number <- how_many_fruits(number)
这就是一个函数应该如何工作:它接受输入(此处称为 num
)并 returns 输出(此处称为 new_num
)。请注意输入和输出的名称 inside 函数不必与您在函数 outside 中使用的变量名称相同。当您调用 how_many_fruits(number)
时,number
的内容存储在 num
中,该函数仅适用于后者。当您执行 number <- how_many_fruits(number)
时,作为 how_many_fruits(number)
结果返回的任何内容都存储在 number
.
直接从函数中修改全局环境不是一个好主意。通常,只 return 一个值并让用户将其附加到需要的地方是一个更好的主意。 (正如 Stibu 解释的那样)。
但是,您也可以使用嵌套环境,如下面对官方 R 语言定义中的示例进行的修改:
fruitscollector <- function(){
fruitslist <- NULL
function(){
answer <- as.integer(readline(prompt="How Many?: "))
fruitslist <<- c(fruitslist, answer)
fruitslist
}
}
所以当您第一次初始化一个 "fruitscollector" 时,它 return 只是一个可以收集值的函数。
foo <- fruitscollector()
现在每次使用 foo
时,都会将一个值添加到集合中(整个集合是 returned):
foo()
foo()
# etc
fruitslist
存储在 foo
的父环境中,因此不在您可能会意外删除它的全局环境中。
编辑
一个更一般的想法是创建一个对象(有点类似于 OOP 中所谓的 "object"),函数作为方法,例如
collector <- function(){
stack <- NULL
list(
add = function(x) stack<<-c(stack, x),
get = function() stack,
empty = function() stack <<- NULL
)
}
现在 add
方法将添加到堆栈,get
方法将 return 整个堆栈,而 empty
方法将清空它。
foo <- collector() # initialize
foo$get() # NULL
foo$add(1) # add 1 to the stack
foo$get() # 1
foo$add(3) # add 3 to the stack
foo$get() # 1 3
foo$add(1:5) # etc...