【问题标题】:R lazy evaluation paradox (R bug?)R 惰性求值悖论(R bug?)
【发布时间】:2015-03-27 09:45:40
【问题描述】:

我有多个函数处理可能丢失的参数。

例如我有

mainfunction <- function(somearg) {
    mytest(somearg)
    fun <- function() { subfunction(somearg) }
    fun()
}

有趣的是,mytest(somearg) 与 arg 的唯一交互是它测试参数是否缺失:

mytest = function(somearg) {
    print(missing(somearg))
}

subfunction 然后再次测试它是否丢失并相应地处理它:

subfunction = function(somearg) {
    if (missing(somearg))
        somearg = NULL
    else
        somearg = matrix(somearg, cols = 2)
    # somearg is used here…
}

问题在于,缺少somearg,这不起作用:matrix(somearg, cols = 2) throws

缺少参数“somearg”,没有默认值

在调试过程中,我发现了以下内容:

  1. mainfunction的开头,missing(somearg)返回TRUE
  2. mytestmissing(somearg) 返回TRUE
  3. insubfunction, missing(somearg) 返回FALSE (!!!!)

因此matrix 分支被命中,但实际上,somearg 丢失了,所以它失败了……

笏。

【问题讨论】:

  • 我猜这里的问题是你不直接调用subfunction,而是从一个嵌套函数中调用,它在参数somearg上创建了一个闭包。似乎闭包不能处理缺失的参数。我不确定这是错误还是“设计使然”:在 fun 内部,somearg 不是参数,它是一个普通变量,因此不能丢失。
  • 查看文档:“目前missing只能在定义参数的函数的直接主体中使用,不能在嵌套函数或local调用的主体中使用。”
  • 虽然missing 很好,但我发现在这种情况下将NULL 作为显式缺失值传递要容易得多;它使函数文档略显丑陋,但在测试is.null(arg) 时从来没有这样的问题。
  • 顺便说一句,@BenBolker 如果你结合我做错了什么以及如何在一个简短的答案中规避它,我很高兴打勾:D
  • 当然是@Roland(但我只能在评论中提及一个人(‽))

标签: r promise lazy-evaluation


【解决方案1】:

@BenBolker 方式:

mainfunction <- function(somearg = NULL) {
    mytest(somearg)
    fun <- function() { subfunction(somearg) }
    fun()
}

mytest = function(somearg) {
    print(is.null(somearg))
}

subfunction = function(somearg) {
    if (is.null(somearg))
        somearg = 1:10
    else
        somearg = matrix(somearg, ncol = 2)
   somearg
}

另一种方式,使用显式缺失参数

mainfunction <- function(somearg) {
    is_missing <- missing(somearg)
    mytest(is_missing)
    fun <- function() { subfunction(somearg, is_missing) }
    fun()
}
mytest = function(x) {  print(x) }
subfunction = function(somearg, is_arg_missing) {
    if (is_arg_missing)
        somearg = 1:10
    else
        somearg = matrix(somearg, ncol = 2)
   somearg
}

第三种方式,使用普通的缺失参数传递:

    mainfunction <- function(somearg) {
        is_missing <- missing(somearg)
        mytest(somearg)
        fun <- function() { 
          if (is_missing) subfunction() else 
              subfunction(somearg) 
        }
        fun()
    }

    mytest = function(somearg) {
        print(missing(somearg))
    }

    subfunction = function(somearg) {
        if (missing(somearg))
            somearg = 1:10
        else
            somearg = matrix(somearg, ncol = 2)
       somearg
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-12
    • 1970-01-01
    • 2022-06-23
    • 1970-01-01
    • 2013-01-30
    • 1970-01-01
    • 1970-01-01
    • 2014-06-23
    相关资源
    最近更新 更多