【问题标题】:How to assign to global variable from a function when masking existing object?屏蔽现有对象时如何从函数分配给全局变量?
【发布时间】:2019-11-05 09:36:12
【问题描述】:

我有这样的功能:

myfun <- function ()
{
    df <<- data.frame(a = 1)
}
myfun()

但它报告错误“myfun() 中的错误:无法更改 'df' 的锁定绑定值”。我真的需要修改全局变量 df 并且我不在乎是否屏蔽现有函数。我该怎么做?

我发现了这个解决方案。它可以工作,但有什么不那么复杂的吗?

myfun <- function ()
{
    df <- data.frame(a = 1)
    assign("df", df, envir = .GlobalEnv)
}
myfun()

【问题讨论】:

    标签: r


    【解决方案1】:

    这里的最佳解决方案是完全避免处理函数内部的变量范围。如果您想创建一个可用于分配数据框变量的函数,则只需让该函数返回数据框:

    myfun <- function() {
        df <- data.frame(a = 1)
        return(df)
    }
    
    # from some calling scope
    mydf <- myfun()
    

    如果您希望在某个范围内分配数据框,则让该范围进行分配,而不是让函数执行此操作。

    【讨论】:

    • 我知道这是可能的,我不是初学者 ;-) 如果这对我来说是一个解决方案,我不会问 :-) 我的函数也返回许多其他变量。 attach(myfun()) 的解决方案是不可接受的,因为它处于 for 循环中。
    • 一般来说,如果您需要一个 R 函数来联系并在其他范围内进行分配,这可能表明设计有异味。您可能不需要这样做。
    • 那是理想主义的想法。跟随它意味着冗长的丑陋代码而不是简单优雅的代码......所以这是我特别询问分配给全局变量的原因,这不是解决方案。
    • @TMS 不,这是功能的想法。 Tim“丑陋的代码”给出的例子如何?我认为它在语法上更干净。底线是您不应该使用&lt;&lt;-assign 分配给全局环境中的变量。 SO上有很多帖子解释了为什么这是一个坏主意。如果您想避免复制数据,或许可以选择使用(伪)OOP 系统,如 R6 或参考类。
    【解决方案2】:

    @TimBiegeleisen 的回答没有什么可补充的;但是,为了响应您的帖子和您看到的错误,您需要在函数范围之外声明 df

    以下作品

    df <- data.frame()
    myfun <- function () df <<- data.frame(a = 1)
    myfun()
    df
    #  a
    #1 1
    

    但是请注意,这不是应该如何使用&lt;&lt;-,请参阅Dirk Eddelbuettel's answer to "What is the difference between assign and &lt;&lt;- in R"。总结一下:

    • 您可以使用 &lt;&lt;- 更新父(但不是全局)环境中的对象(具有词法范围的“超级赋值”),反之亦然
    • 不要使用 &lt;&lt;- 来更新全局环境中的对象。

    【讨论】:

    • 如果在预期的df 对象之前发现df 对象,它将被静默更新,调试可能会很痛苦
    猜你喜欢
    • 2020-11-15
    • 1970-01-01
    • 2020-07-06
    • 2017-06-25
    • 1970-01-01
    • 2014-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多