【问题标题】:Access global variable within function访问函数内的全局变量
【发布时间】:2019-06-21 10:02:10
【问题描述】:

我有两个 data.frames df1errors 和一个函数 add_to_errors()。该函数的参数是一个行号向量(df1),该函数应将所选行添加到名为 errors 的新 data.frame 中。

df1 <- data.frame(id=1:10,
                  var1=rep(NA, 2),
                  var2=rep(NA, 2))

errors <- data.frame()

add_to_errors <- function(ids){
    rows_to_add <- df1[ids,]
    errors <- rbind(errors, rows_to_add)
    return(errors)
} 

add_to_errors(c(1,2))
add_to_errors(c(6,7))

当我执行add_to_errors(1, 2)add_to_errors(6,7) 时,每次调用该函数时似乎都会覆盖errors。如何将errors 作为函数内的全局变量访问?

输出应如下所示:

  id var1 var2
1  1   NA   NA
2  2   NA   NA
3  6   NA   NA
4  7   NA   NA 

【问题讨论】:

    标签: r function global-variables


    【解决方案1】:

    我建议不要使用父作用域运算符&lt;&lt;-,而是使用具有适当设计和封装的函数:

    add_to_errors <- function(df1, ids, errors) {
        rows_to_add <- df1[ids,]
        errors <- rbind(errors, rows_to_add)
        return(errors)
    }
    
    df1 <- data.frame(id=1:10, var1=rep(NA, 2), var2=rep(NA, 2))
    errors <- data.frame()
    errors <- add_to_errors(df1, c(1,2), errors)
    errors <- add_to_errors(df1, c(6,7), errors)
    errors
    
      id var1 var2
    1  1   NA   NA
    2  2   NA   NA
    6  6   NA   NA
    7  7   NA   NA
    

    上述函数已被重构为接受所有需要的参数作为输入,输出是使用您的逻辑生成的数据帧。调用它时,我们用返回值破坏(覆盖)输入数据帧。

    【讨论】:

    • 我本来想推荐这个的,但你到了!这绝对是要走的路。应避免副作用。
    • @LyzanderR 作为一次性脚本,您的回答完全没问题。但是在构建更大的代码时,&lt;&lt;- 会变得难以控制:P
    【解决方案2】:

    一种方法是使用&lt;&lt;-,如下所示:

    add_to_errors <- function(ids){
      rows_to_add <- df1[ids,]
      errors <<- rbind(errors, rows_to_add)
      return(errors)
    } 
    
    add_to_errors(c(1,2))
    #  id var1 var2
    #1  1   NA   NA
    #2  2   NA   NA
    add_to_errors(c(6,7))
    #  id var1 var2
    #1  1   NA   NA
    #2  2   NA   NA
    #6  6   NA   NA
    #7  7   NA   NA
    

    在函数内通过&lt;&lt;- 更改全局环境不被认为是好的做法(这称为副作用,最好避免 - 如果可能 - 因为它会产生错误)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多