在R中将值从函数绑定到全局环境

时间:2016-05-21 07:11:10

标签: r environments

我无法理解如何将函数内的值绑定到函数外部的环境。一个基本的例子如下所示,我似乎无法解决函数的最后一部分:

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的底部数据框。

2 个答案:

答案 0 :(得分:4)

您可以使用<<-运算符:

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)并返回一个输出(此处称为new_num)。注意函数中输入和输出的名称​​的名称不必与 outside 函数的变量名称相同。当您致电how_many_fruits(number)时,number的内容会存储在num中,而该功能仅适用于后者。当您执行number <- how_many_fruits(number)时,how_many_fruits(number)的结果中返回的任何内容都会存储在number中。

答案 1 :(得分:3)

直接从函数中修改全局环境不是一个好主意。通常,最好只返回一个值并让用户将其附加到必要的位置。 (就像Stibu解释的那样)。

但是,您还可以使用嵌套环境,如以下对官方R语言定义中的示例的修改:

fruitscollector <- function(){
  fruitslist <- NULL
  function(){
    answer <- as.integer(readline(prompt="How Many?: "))
    fruitslist <<- c(fruitslist, answer)
    fruitslist
  }
}

因此,当您首次初始化“fruitscollector”时,它只返回一个可以收集值的函数。

foo <- fruitscollector()

现在每次使用foo时,都会在集合中添加一个值(并返回整个集合):

foo()
foo()
# etc

fruitslist存储在foo的父环境中,因此不会在您可能意外删除它的全局环境中。

修改

更一般的想法是创建一个对象(有点类似于OOP中所谓的“对象”),其功能为方法,例如。

collector <- function(){
  stack <- NULL
  list(
    add = function(x) stack<<-c(stack, x),
    get = function() stack,
    empty = function() stack <<- NULL
  )
}

现在add方法将添加到堆栈中,get方法将返回整个堆栈,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...