【问题标题】:How to check if object (variable) is defined in R?如何检查对象(变量)是否在 R 中定义?
【发布时间】:2012-03-11 06:03:18
【问题描述】:

我想检查是否在 R 中定义了某个变量 - 没有出现错误。我该怎么做?

我的尝试(不成功):

> is.na(ooxx)
Error: object 'ooxx' not found
> is.finite(ooxx)
Error: object 'ooxx' not found

谢谢!

【问题讨论】:

    标签: r


    【解决方案1】:

    你想要exists():

    R> exists("somethingUnknown")
    [1] FALSE
    R> somethingUnknown <- 42
    R> exists("somethingUnknown")
    [1] TRUE
    R> 
    

    【讨论】:

    • @Gavin & Dirk,你们对彼此太好了 :) 唯一的解决办法是你扔硬币(伯努利 p=0.5 :-))谁会被接受! :-)
    • @tim 如果你在一个函数中,missing() 就是你想要的。
    • 如果检查列表元素可能会有点棘手:stackoverflow.com/q/7719741
    • op 想要什么 - 使用变量名,而不是引号?
    【解决方案2】:

    请参阅?exists,了解“.​​..已定义”的一些定义。例如

    > exists("foo")
    [1] FALSE
    > foo <- 1:10
    > exists("foo")
    [1] TRUE
    

    【讨论】:

    • @DirkEddelbuettel 好吧,如果你会使用长得离谱的对象名称 ;-)
    • 嘿。当我在发布之前测试示例时,一直发生在我身上,Gavin 或 Josh 已经回答了。
    【解决方案3】:

    如果你在函数内部,missing() 就是你想要的。

    exchequer = function(x) {
        if(missing(x)){
            message("x is missing… :-(")
        }
    }
    
    exchequer()
    x is missing… :-(
    

    【讨论】:

    • missing 仅适用于函数参数。你不能这样做foo &lt;- function(x) {missing(x); missing(y)},否则你会得到foo(1)&gt; Error in missing(y) : 'missing' can only be used for arguments
    【解决方案4】:

    正如其他人指出的那样,您正在寻找exists。请记住,将 exists 与 R 的基本包使用的名称一起使用将返回 true,无论您是否定义了变量:

    > exists("data")
    [1] TRUE
    

    要解决这个问题(正如 Bazz 指出的那样;请参阅 ?exists),请使用 inherits 参数:

    > exists("data", inherits = FALSE)
    [1] FALSE
    
    foo <- TRUE
    > exists("foo", inherits = FALSE)
    [1] TRUE
    

    当然,如果你想搜索附加包的名称空间,这也是不够的:

    > exists("data.table")
    [1] FALSE
    require(data.table)
    > exists("data.table", inherits = FALSE)
    [1] FALSE
    > exists("data.table")
    [1] TRUE
    

    我能想到解决这个问题的唯一方法——在附加包中搜索,但不是在基本包中搜索——如下:

    any(sapply(1:(which(search() == "tools:rstudio") - 1L),
               function(pp) exists(_object_name_, where = pp, inherits = FALSE)))
    

    比较将_object_name_ 替换为"data.table" (TRUE) 与"var" (FALSE)

    (当然,如果你不在RStudio上,我认为第一个自动附加的环境是"package:stats"

    【讨论】:

    • 玩弄,使用参数inherits = FALSE 似乎隔离了全局环境中的事物。听起来对吗?
    • @Bazz 你是对的;我已将其编辑为答案。
    • 这个注释应该更高,因为我使用变量名“data”,刚开始使用exist给我带来了一些麻烦。
    【解决方案5】:

    如果您不想使用引号,可以使用我在?substitute 示例部分中找到的deparse(substitute()) 技巧:

    is.defined <- function(sym) {
      sym <- deparse(substitute(sym))
      env <- parent.frame()
      exists(sym, env)
    }
    
    is.defined(a)
    # FALSE
    a <- 10
    is.defined(a)
    # TRUE
    

    【讨论】:

    • 您也可以force 或在函数中评估它,如下所示:is.defined &lt;- function(sym) class(try(sym, TRUE))!='try-error'
    • 这个答案可能有点复杂......但如果您不想与字符与 var-names 抗衡,这是理想的答案
    • 我遇到了一个需要您解决的问题。当您想使用不是NULL 的东西作为quosure(enquo(x) 如果x 不为空)时,您需要一种检查传入的表达式是否不为空的好方法。您的解决方案正是这样做的。谢谢
    【解决方案6】:

    在某些情况下,您可能并不确切知道要查找的变量的名称,例如队列系统创建了一个结果数组。这些可以用“ls”和它的参数“pattern”来解决,它需要一个正则表达式。

    “exists”函数可以这样重新实现

    exists <-function(variablename) {
       #print(ls(env=globalenv()))
       return(1==length(ls(pattern=paste("^",variablename,"$",sep=""),env=globalenv())))
    }
    

    在准备这个答案时,我对从函数中调用 ls() 时需要环境规范的需要感到有些惊讶。所以,谢谢你,stackoverflow!还有一个“all.names”属性,我应该设置为 true 但已省略。

    【讨论】:

      【解决方案7】:

      如果你不介意使用引号,你可以使用:

      存在(“x”)

      如果你不想使用引号,你可以使用:

      存在(deparse(substitute(x)))

      【讨论】:

      • 这个答案结合了以前的答案。不确定这是否会为目前的对话添加任何内容。
      猜你喜欢
      • 2011-12-10
      • 1970-01-01
      • 1970-01-01
      • 2021-08-26
      • 1970-01-01
      • 2013-05-19
      • 2019-05-11
      • 1970-01-01
      相关资源
      最近更新 更多