【问题标题】:Scoping difference between missing() and is.null()missing() 和 is.null() 之间的范围差异
【发布时间】:2020-01-16 15:10:16
【问题描述】:

我很难理解is.nullmissing 之间的作用域差异,特别是为什么以下内容不适用于is.null,但适用于missing

foo_iris <- function(a = NULL){
  if(!is.null(a)) return('not.null') else  return('is.null')
}

foo_iris(a = Species)
#> Error in foo_iris(a = Species): object 'Species' not found

foo_iris <- function(a = NULL){
  if(missing(a)) return('is.null') else return('not.null')
}

foo_iris(a = Species)
#> [1] "not.null"

reprex package (v0.3.0) 于 2020-01-16 创建

【问题讨论】:

    标签: r


    【解决方案1】:

    这与范围无关。

    R 具有惰性求值,这意味着仅在必要时才对参数进行求值。 is.null 需要评估 a 以检查它是否是对 NULL 对象的引用。此评估会引发错误。 missing 不评估 a,请参阅 help("missing") 中的文档:

    这是一个“特殊”的原始函数:它不能评估它的 论据。

    【讨论】:

    • 谢谢。这是有道理的
    • ...然而,这在某种程度上与范围界定...??因为当我在全局环境中定义一个 NULL 对象Species&lt;-NULL 时,该函数起作用了。抱歉,在相当深刻的层面上理解这一点可能有困难
    • 嗯,这只是标准范围。为什么使用missing 的函数没有错误的解释是参数评估而不是范围。如果您坚信答案应该涉及范围界定,我可能会误解您的问题。
    • 不不,没关系,我认为是我误解了一些基本概念,不幸的是......感谢您的帮助!
    【解决方案2】:

    你需要修改你的代码如下:

    foo_iris <- function(a = NULL){
        if(exists(deparse(substitute(a))) && !is.null(a)) return('not.null') else  return('is.null')
    }
    
    foo_iris(a = Species)
    

    这里exists(deparse(substitute(a))) 检查对象是否存在。这与惰性 AND 运算符 &amp;&amp; 一起计算 is.null()。没有惰性 eval is.null() 会因为对象不存在而失败。

    【讨论】:

    • 我想我更喜欢使用missing,但这仍然很有趣
    猜你喜欢
    • 2013-04-12
    • 2015-02-24
    • 1970-01-01
    • 2011-10-07
    • 2021-06-22
    • 2017-12-12
    • 2012-04-24
    • 2014-03-09
    • 1970-01-01
    相关资源
    最近更新 更多